# HG changeset patch
# User Alex Williamson <alex.williamson@xxxxxx>
# Date 1175296722 21600
# Node ID fc9e2f7920c95229caaf5ad8fc44965dd891f600
# Parent e7da2fcb7a226a4a96a97f1c17711649309aa15c
# Parent b0b20a09d2534a97dd871c1fe787af9a32864c0c
merge with xen-unstable.hg
---
.hgignore | 1
Config.mk | 14
docs/xen-api/xenapi-datamodel.tex | 273 ++
linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S | 16
linux-2.6-xen-sparse/arch/x86_64/kernel/head64-xen.c | 2
linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c | 2
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c | 1
linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c | 2
linux-2.6-xen-sparse/drivers/xen/core/reboot.c | 19
linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c | 35
linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_capability_pm.c | 35
linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_header.c | 14
linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c | 53
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c | 104
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c | 60
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.h | 1
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe_backend.c | 25
tools/Rules.mk | 6
tools/examples/Makefile | 2
tools/examples/xend-config-xenapi.sxp | 195 +
tools/examples/xend-config.sxp | 14
tools/examples/xm-config-xenapi.xml | 43
tools/ioemu/hw/ne2000.c | 13
tools/ioemu/hw/pcnet.c | 58
tools/ioemu/hw/piix4acpi.c | 20
tools/ioemu/hw/rtl8139.c | 9
tools/ioemu/hw/usb-uhci.c | 1
tools/ioemu/vl.c | 7
tools/libxc/xc_hvm_restore.c | 29
tools/libxen/Makefile | 3
tools/libxen/include/xen_event.h | 102
tools/libxen/include/xen_event_decl.h | 25
tools/libxen/include/xen_event_operation.h | 82
tools/libxen/include/xen_event_operation_internal.h | 37
tools/libxen/include/xen_network.h | 33
tools/libxen/src/xen_common.c | 132 -
tools/libxen/src/xen_event.c | 123
tools/libxen/src/xen_event_operation.c | 75
tools/libxen/src/xen_network.c | 74
tools/libxen/test/test_event_handling.c | 211 +
tools/pygrub/src/pygrub | 17
tools/python/xen/lowlevel/xc/xc.c | 28
tools/python/xen/util/xmlrpcclient.py | 123
tools/python/xen/util/xmlrpclib2.py | 71
tools/python/xen/xend/XendAPI.py | 400 ++-
tools/python/xen/xend/XendCheckpoint.py | 8
tools/python/xen/xend/XendClient.py | 2
tools/python/xen/xend/XendConfig.py | 15
tools/python/xen/xend/XendConstants.py | 7
tools/python/xen/xend/XendDomain.py | 20
tools/python/xen/xend/XendDomainInfo.py | 20
tools/python/xen/xend/XendLogging.py | 1
tools/python/xen/xend/XendMonitor.py | 16
tools/python/xen/xend/XendNetwork.py | 43
tools/python/xen/xend/XendNode.py | 32
tools/python/xen/xend/XendOptions.py | 8
tools/python/xen/xend/XendPIFMetrics.py | 8
tools/python/xen/xend/XendStateStore.py | 13
tools/python/xen/xend/XendVMMetrics.py | 11
tools/python/xen/xend/server/SSLXMLRPCServer.py | 103
tools/python/xen/xend/server/SrvDaemon.py | 94
tools/python/xen/xend/server/SrvServer.py | 96
tools/python/xen/xend/server/XMLRPCServer.py | 50
tools/python/xen/xm/XenAPI.py | 16
tools/python/xen/xm/create.dtd | 17
tools/python/xen/xm/create.py | 68
tools/python/xen/xm/main.py | 68
tools/python/xen/xm/messages/en/xen-xm.po | 5
tools/python/xen/xm/opts.py | 19
tools/python/xen/xm/xenapi_create.py | 193 +
tools/security/policies/security_policy.xsd | 15
tools/security/secpol_tool.c | 62
tools/security/secpol_xml2bin.c | 78
tools/security/secpol_xml2bin.h | 60
tools/xcutils/xc_restore.c | 2
tools/xm-test/lib/XmTestLib/XenAPIDomain.py | 1
tools/xm-test/tests/destroy/06_destroy_dom0_neg.py | 2
unmodified_drivers/linux-2.6/platform-pci/platform-pci.c | 35
xen/acm/acm_chinesewall_hooks.c | 13
xen/acm/acm_core.c | 67
xen/acm/acm_null_hooks.c | 2
xen/acm/acm_policy.c | 42
xen/acm/acm_simple_type_enforcement_hooks.c | 26
xen/arch/ia64/asm-offsets.c | 9
xen/arch/ia64/linux-xen/irq_ia64.c | 2
xen/arch/ia64/linux-xen/mca.c | 10
xen/arch/ia64/linux-xen/smp.c | 2
xen/arch/ia64/vmx/pal_emul.c | 2
xen/arch/ia64/vmx/vlsapic.c | 8
xen/arch/ia64/vmx/vmmu.c | 2
xen/arch/ia64/vmx/vmx_process.c | 2
xen/arch/ia64/vmx/vmx_support.c | 4
xen/arch/ia64/vmx/vmx_virt.c | 78
xen/arch/ia64/xen/dom0_ops.c | 4
xen/arch/ia64/xen/domain.c | 26
xen/arch/ia64/xen/faults.c | 2
xen/arch/ia64/xen/fw_emul.c | 4
xen/arch/ia64/xen/hypercall.c | 20
xen/arch/ia64/xen/hyperprivop.S | 13
xen/arch/ia64/xen/mm.c | 31
xen/arch/ia64/xen/privop.c | 30
xen/arch/ia64/xen/privop_stat.c | 86
xen/arch/ia64/xen/tlb_track.c | 42
xen/arch/ia64/xen/vcpu.c | 10
xen/arch/ia64/xen/vhpt.c | 40
xen/arch/powerpc/backtrace.c | 15
xen/arch/powerpc/domain.c | 11
xen/arch/powerpc/domain_build.c | 4
xen/arch/powerpc/mm.c | 12
xen/arch/x86/Rules.mk | 4
xen/arch/x86/apic.c | 2
xen/arch/x86/domain.c | 16
xen/arch/x86/domain_build.c | 8
xen/arch/x86/domctl.c | 4
xen/arch/x86/extable.c | 2
xen/arch/x86/hvm/hvm.c | 35
xen/arch/x86/hvm/io.c | 64
xen/arch/x86/hvm/save.c | 2
xen/arch/x86/hvm/svm/emulate.c | 4
xen/arch/x86/hvm/svm/intr.c | 122
xen/arch/x86/hvm/svm/svm.c | 1248
++--------
xen/arch/x86/hvm/svm/vmcb.c | 8
xen/arch/x86/hvm/vlapic.c | 4
xen/arch/x86/hvm/vmx/intr.c | 35
xen/arch/x86/hvm/vmx/vmcs.c | 131 -
xen/arch/x86/hvm/vmx/vmx.c | 213 -
xen/arch/x86/hvm/vpt.c | 2
xen/arch/x86/i387.c | 4
xen/arch/x86/irq.c | 2
xen/arch/x86/mm.c | 48
xen/arch/x86/mm/hap/hap.c | 23
xen/arch/x86/mm/paging.c | 15
xen/arch/x86/mm/shadow/common.c | 44
xen/arch/x86/mm/shadow/multi.c | 62
xen/arch/x86/nmi.c | 16
xen/arch/x86/smp.c | 6
xen/arch/x86/time.c | 22
xen/arch/x86/traps.c | 30
xen/arch/x86/x86_32/asm-offsets.c | 19
xen/arch/x86/x86_32/domain_page.c | 6
xen/arch/x86/x86_32/entry.S | 18
xen/arch/x86/x86_32/seg_fixup.c | 2
xen/arch/x86/x86_32/traps.c | 2
xen/arch/x86/x86_64/asm-offsets.c | 34
xen/arch/x86/x86_64/compat/entry.S | 17
xen/arch/x86/x86_64/compat/traps.c | 2
xen/arch/x86/x86_64/entry.S | 44
xen/arch/x86/x86_64/traps.c | 2
xen/arch/x86/x86_emulate.c | 12
xen/common/compat/domain.c | 2
xen/common/domain.c | 124
xen/common/domctl.c | 77
xen/common/event_channel.c | 19
xen/common/grant_table.c | 16
xen/common/kernel.c | 2
xen/common/keyhandler.c | 8
xen/common/memory.c | 6
xen/common/multicall.c | 5
xen/common/page_alloc.c | 6
xen/common/perfc.c | 223 -
xen/common/sched_credit.c | 5
xen/common/sched_sedf.c | 2
xen/common/schedule.c | 81
xen/drivers/char/console.c | 10
xen/include/acm/acm_core.h | 10
xen/include/acm/acm_hooks.h | 12
xen/include/asm-ia64/bug.h | 1
xen/include/asm-ia64/event.h | 6
xen/include/asm-ia64/linux-xen/asm/asmmacro.h | 4
xen/include/asm-ia64/linux-xen/asm/iosapic.h | 19
xen/include/asm-ia64/mm.h | 5
xen/include/asm-ia64/perfc_defn.h | 214 -
xen/include/asm-ia64/privop_stat.h | 25
xen/include/asm-ia64/tlb_track.h | 4
xen/include/asm-ia64/vmx_vpd.h | 3
xen/include/asm-powerpc/bug.h | 1
xen/include/asm-powerpc/debugger.h | 4
xen/include/asm-powerpc/event.h | 8
xen/include/asm-powerpc/mm.h | 5
xen/include/asm-x86/bug.h | 6
xen/include/asm-x86/debugger.h | 3
xen/include/asm-x86/event.h | 6
xen/include/asm-x86/hvm/hvm.h | 2
xen/include/asm-x86/hvm/support.h | 41
xen/include/asm-x86/hvm/svm/emulate.h | 1
xen/include/asm-x86/hvm/svm/vmcb.h | 1
xen/include/asm-x86/hvm/vcpu.h | 4
xen/include/asm-x86/hvm/vmx/vmcs.h | 20
xen/include/asm-x86/hvm/vmx/vmx.h | 28
xen/include/asm-x86/i387.h | 11
xen/include/asm-x86/mm.h | 5
xen/include/asm-x86/msr.h | 4
xen/include/asm-x86/multicall.h | 104
xen/include/asm-x86/perfc_defn.h | 126 -
xen/include/asm-x86/x86_32/asm_defns.h | 12
xen/include/asm-x86/x86_32/bug.h | 6
xen/include/asm-x86/x86_64/asm_defns.h | 19
xen/include/asm-x86/x86_64/bug.h | 6
xen/include/public/acm.h | 26
xen/include/public/foreign/Makefile | 4
xen/include/xen/event.h | 6
xen/include/xen/lib.h | 4
xen/include/xen/list.h | 704
+++++
xen/include/xen/perfc.h | 120
xen/include/xen/perfc_defn.h | 15
xen/include/xen/sched.h | 139 -
xen/include/xen/spinlock.h | 7
xen/include/xen/types.h | 2
208 files changed, 5559 insertions(+), 3511 deletions(-)
diff -r e7da2fcb7a22 -r fc9e2f7920c9 .hgignore
--- a/.hgignore Fri Mar 30 10:27:15 2007 -0600
+++ b/.hgignore Fri Mar 30 17:18:42 2007 -0600
@@ -126,6 +126,7 @@
^tools/ioemu/qemu\.pod$
^tools/libxc/xen/.*$
^tools/libxen/test/test_bindings$
+^tools/libxen/test/test_event_handling$
^tools/libaio/src/.*\.ol$
^tools/libaio/src/.*\.os$
^tools/misc/cpuperf/cpuperf-perfcntr$
diff -r e7da2fcb7a22 -r fc9e2f7920c9 Config.mk
--- a/Config.mk Fri Mar 30 10:27:15 2007 -0600
+++ b/Config.mk Fri Mar 30 17:18:42 2007 -0600
@@ -31,16 +31,26 @@ EXTRA_LIB += $(EXTRA_PREFIX)/$(LIBDIR)
EXTRA_LIB += $(EXTRA_PREFIX)/$(LIBDIR)
endif
-# cc-option
+# cc-option: Check if compiler supports first option, else fall back to second.
# Usage: cflags-y += $(call cc-option,$(CC),-march=winchip-c6,-march=i586)
cc-option = $(shell if test -z "`$(1) $(2) -S -o /dev/null -xc \
/dev/null 2>&1`"; then echo "$(2)"; else echo "$(3)"; fi ;)
-# cc-ver
+# cc-ver: Check compiler is at least specified version. Return boolean 'y'/'n'.
# Usage: ifeq ($(call cc-ver,$(CC),0x030400),y)
cc-ver = $(shell if [ $$((`$(1) -dumpversion | awk -F. \
'{ printf "0x%02x%02x%02x", $$1, $$2, $$3}'`)) -ge $$(($(2))) ]; \
then echo y; else echo n; fi ;)
+
+# cc-ver-check: Check compiler is at least specified version, else fail.
+# Usage: $(call cc-ver-check,CC,0x030400,"Require at least gcc-3.4")
+cc-ver-check = $(eval $(call cc-ver-check-closure,$(1),$(2),$(3)))
+define cc-ver-check-closure
+ ifeq ($$(call cc-ver,$$($(1)),$(2)),n)
+ override $(1) = echo "*** FATAL BUILD ERROR: "$(3) >&2; exit 1;
+ cc-option := n
+ endif
+endef
ifneq ($(debug),y)
CFLAGS += -DNDEBUG
diff -r e7da2fcb7a22 -r fc9e2f7920c9 docs/xen-api/xenapi-datamodel.tex
--- a/docs/xen-api/xenapi-datamodel.tex Fri Mar 30 10:27:15 2007 -0600
+++ b/docs/xen-api/xenapi-datamodel.tex Fri Mar 30 17:18:42 2007 -0600
@@ -24,6 +24,7 @@ Name & Description \\
\hline
{\tt session} & A session \\
{\tt task} & A long-running asynchronous task \\
+{\tt event} & Asynchronous event registration and handling \\
{\tt VM} & A virtual machine (or 'guest') \\
{\tt VM\_metrics} & The metrics associated with a VM \\
{\tt VM\_guest\_metrics} & The metrics reported by the guest (as opposed to
inferred from outside) \\
@@ -112,6 +113,17 @@ The following enumeration types are used
\begin{longtable}{|ll|}
\hline
+{\tt enum event\_operation} & \\
+\hline
+\hspace{0.5cm}{\tt add} & An object has been created \\
+\hspace{0.5cm}{\tt del} & An object has been deleted \\
+\hspace{0.5cm}{\tt mod} & An object has been modified \\
+\hline
+\end{longtable}
+
+\vspace{1cm}
+\begin{longtable}{|ll|}
+\hline
{\tt enum console\_protocol} & \\
\hline
\hspace{0.5cm}{\tt vt100} & VT100 terminal \\
@@ -1013,6 +1025,116 @@ references to objects with match names
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
+
+\vspace{1cm}
+\newpage
+\section{Class: event}
+\subsection{Fields for class: event}
+\begin{longtable}{|lllp{0.38\textwidth}|}
+\hline
+\multicolumn{1}{|l}{Name} & \multicolumn{3}{l|}{\bf event} \\
+\multicolumn{1}{|l}{Description} & \multicolumn{3}{l|}{\parbox{11cm}{\em
+Asynchronous event registration and handling.}} \\
+\hline
+Quals & Field & Type & Description \\
+\hline
+$\mathit{RO}_\mathit{ins}$ & {\tt id} & int & An ID, monotonically
increasing, and local to the current session \\
+$\mathit{RO}_\mathit{ins}$ & {\tt timestamp} & datetime & The time at which
the event occurred \\
+$\mathit{RO}_\mathit{ins}$ & {\tt class} & string & The name of the class of
the object that changed \\
+$\mathit{RO}_\mathit{ins}$ & {\tt operation} & event\_operation & The
operation that was performed \\
+$\mathit{RO}_\mathit{ins}$ & {\tt ref} & string & A reference to the object
that changed \\
+$\mathit{RO}_\mathit{ins}$ & {\tt obj\_uuid} & string & The uuid of the
object that changed \\
+\hline
+\end{longtable}
+\subsection{RPCs associated with class: event}
+\subsubsection{RPC name:~register}
+
+{\bf Overview:}
+Registers this session with the event system. Specifying the empty list
+will register for all classes.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void register (session_id s, string Set classes)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt string Set } & classes & register for events for the indicated classes \\
\hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~unregister}
+
+{\bf Overview:}
+Unregisters this session with the event system.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void unregister (session_id s, string Set
classes)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt string Set } & classes & remove this session's registration for the
indicated classes \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~next}
+
+{\bf Overview:}
+Blocking call which returns a (possibly empty) batch of events.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} ((event record) Set) next (session_id s)\end{verbatim}
+
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+(event record) Set
+}
+
+
+the batch of events
+\vspace{0.3cm}
+
+\noindent{\bf Possible Error Codes:} {\tt SESSION\_NOT\_REGISTERED}
+
+\vspace{0.6cm}
\vspace{1cm}
\newpage
@@ -6549,6 +6671,7 @@ Quals & Field & Type & Description \\
$\mathit{RW}$ & {\tt name/description} & string & a notes field containg
human-readable description \\
$\mathit{RO}_\mathit{run}$ & {\tt VIFs} & (VIF ref) Set & list of connected
vifs \\
$\mathit{RO}_\mathit{run}$ & {\tt PIFs} & (PIF ref) Set & list of connected
pifs \\
+$\mathit{RW}$ & {\tt other\_config} & (string $\rightarrow$ string) Map &
additional configuration \\
\hline
\end{longtable}
\subsection{RPCs associated with class: network}
@@ -6798,6 +6921,145 @@ Get the PIFs field of the given network.
value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_other\_config}
+
+{\bf Overview:}
+Get the other\_config field of the given network.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} ((string -> string) Map) get_other_config (session_id s,
network ref self)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt network ref } & self & reference to the object \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+(string $\rightarrow$ string) Map
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~set\_other\_config}
+
+{\bf Overview:}
+Set the other\_config field of the given network.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void set_other_config (session_id s, network ref self,
(string -> string) Map value)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt network ref } & self & reference to the object \\ \hline
+
+{\tt (string $\rightarrow$ string) Map } & value & New value to set \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~add\_to\_other\_config}
+
+{\bf Overview:}
+Add the given key-value pair to the other\_config field of the given
+network.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void add_to_other_config (session_id s, network ref self,
string key, string value)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt network ref } & self & reference to the object \\ \hline
+
+{\tt string } & key & Key to add \\ \hline
+
+{\tt string } & value & Value to add \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~remove\_from\_other\_config}
+
+{\bf Overview:}
+Remove the given key and its corresponding value from the other\_config
+field of the given network. If the key is not in that Map, then do
+nothing.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void remove_from_other_config (session_id s, network ref
self, string key)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt network ref } & self & reference to the object \\ \hline
+
+{\tt string } & key & Key to remove \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
@@ -13576,6 +13838,17 @@ current connection. The handle paramete
\begin{verbatim}SESSION_INVALID(handle)\end{verbatim}
\begin{center}\rule{10em}{0.1pt}\end{center}
+\subsubsection{SESSION\_NOT\_REGISTERED}
+
+This session is not registered to receive events. You must call
+event.register before event.next. The session handle you are using is
+echoed.
+
+\vspace{0.3cm}
+{\bf Signature:}
+\begin{verbatim}SESSION_NOT_REGISTERED(handle)\end{verbatim}
+\begin{center}\rule{10em}{0.1pt}\end{center}
+
\subsubsection{VALUE\_NOT\_SUPPORTED}
You attempted to set a value that is not supported by this implementation.
diff -r e7da2fcb7a22 -r fc9e2f7920c9
linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S Fri Mar 30
10:27:15 2007 -0600
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S Fri Mar 30
17:18:42 2007 -0600
@@ -148,11 +148,11 @@ NMI_MASK = 0x80000000
.endm
/*
- * Must be consistent with the definition in arch-x86_64.h:
+ * Must be consistent with the definition in arch-x86/xen-x86_64.h:
* struct iret_context {
* u64 rax, r11, rcx, flags, rip, cs, rflags, rsp, ss;
* };
- * #define VGCF_IN_SYSCALL (1<<8)
+ * with rax, r11, and rcx being taken care of in the hypercall stub.
*/
.macro HYPERVISOR_IRET flag
testb $3,1*8(%rsp)
@@ -164,21 +164,15 @@ NMI_MASK = 0x80000000
jnz 1f
/* Direct iret to kernel space. Correct CS and SS. */
- orb $3,1*8(%rsp)
- orb $3,4*8(%rsp)
+ orl $3,1*8(%rsp)
+ orl $3,4*8(%rsp)
1: iretq
2: /* Slow iret via hypervisor. */
- andl $~NMI_MASK, 16(%rsp)
+ andl $~NMI_MASK, 2*8(%rsp)
pushq $\flag
jmp hypercall_page + (__HYPERVISOR_iret * 32)
.endm
-
- .macro SWITCH_TO_KERNEL ssoff,adjust=0
- jc 1f
- orb $1,\ssoff-\adjust+4(%rsp)
-1:
- .endm
/*
* A newly forked process directly context switches into this.
diff -r e7da2fcb7a22 -r fc9e2f7920c9
linux-2.6-xen-sparse/arch/x86_64/kernel/head64-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/head64-xen.c Fri Mar 30
10:27:15 2007 -0600
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/head64-xen.c Fri Mar 30
17:18:42 2007 -0600
@@ -104,6 +104,8 @@ void __init x86_64_start_kernel(char * r
char *s;
int i;
+ setup_xen_features();
+
xen_start_info = (struct start_info *)real_mode_data;
if (!xen_feature(XENFEAT_auto_translated_physmap))
phys_to_machine_mapping =
diff -r e7da2fcb7a22 -r fc9e2f7920c9
linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c Fri Mar 30
10:27:15 2007 -0600
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c Fri Mar 30
17:18:42 2007 -0600
@@ -625,8 +625,6 @@ void __init setup_arch(char **cmdline_p)
#endif
- setup_xen_features();
-
HYPERVISOR_vm_assist(VMASST_CMD_enable,
VMASST_TYPE_writable_pagetables);
diff -r e7da2fcb7a22 -r fc9e2f7920c9
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
--- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Fri Mar 30
10:27:15 2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Fri Mar 30
17:18:42 2007 -0600
@@ -43,6 +43,7 @@
#include <linux/bootmem.h>
#include <linux/highmem.h>
#include <linux/vmalloc.h>
+#include <linux/mutex.h>
#include <xen/xen_proc.h>
#include <asm/hypervisor.h>
#include <xen/balloon.h>
diff -r e7da2fcb7a22 -r fc9e2f7920c9
linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c Fri Mar 30
10:27:15 2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c Fri Mar 30
17:18:42 2007 -0600
@@ -123,7 +123,7 @@ static int take_machine_down(void *p_fas
static int take_machine_down(void *p_fast_suspend)
{
int fast_suspend = *(int *)p_fast_suspend;
- int suspend_cancelled, err, cpu;
+ int suspend_cancelled, err;
extern void time_resume(void);
if (fast_suspend) {
diff -r e7da2fcb7a22 -r fc9e2f7920c9
linux-2.6-xen-sparse/drivers/xen/core/reboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c Fri Mar 30 10:27:15
2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c Fri Mar 30 17:18:42
2007 -0600
@@ -33,7 +33,24 @@ static DECLARE_WORK(shutdown_work, __shu
#ifdef CONFIG_XEN
int __xen_suspend(int fast_suspend);
#else
-#define __xen_suspend(fast_suspend) 0
+extern void xenbus_suspend(void);
+extern void xenbus_resume(void);
+extern void platform_pci_suspend(void);
+extern void platform_pci_resume(void);
+int __xen_suspend(int fast_suspend)
+{
+ xenbus_suspend();
+ platform_pci_suspend();
+
+ /* pvdrv sleep in this hyper-call when save */
+ HYPERVISOR_shutdown(SHUTDOWN_suspend);
+
+ platform_pci_resume();
+ xenbus_resume();
+ printk("PV stuff on HVM resume successfully!\n");
+
+ return 0;
+}
#endif
static int shutdown_process(void *__unused)
diff -r e7da2fcb7a22 -r fc9e2f7920c9
linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c
--- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c Fri Mar 30 10:27:15
2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c Fri Mar 30 17:18:42
2007 -0600
@@ -47,6 +47,7 @@
#include <linux/irq.h>
#include <linux/init.h>
#include <linux/gfp.h>
+#include <linux/mutex.h>
#include <xen/evtchn.h>
#include <xen/public/evtchn.h>
@@ -56,6 +57,7 @@ struct per_user_data {
#define EVTCHN_RING_MASK(_i) ((_i)&(EVTCHN_RING_SIZE-1))
evtchn_port_t *ring;
unsigned int ring_cons, ring_prod, ring_overflow;
+ struct mutex ring_cons_mutex; /* protect against concurrent readers */
/* Processes wait on this queue when ring is empty. */
wait_queue_head_t evtchn_wait;
@@ -108,11 +110,16 @@ static ssize_t evtchn_read(struct file *
count = PAGE_SIZE;
for (;;) {
+ mutex_lock(&u->ring_cons_mutex);
+
+ rc = -EFBIG;
if (u->ring_overflow)
- return -EFBIG;
+ goto unlock_out;
if ((c = u->ring_cons) != (p = u->ring_prod))
break;
+
+ mutex_unlock(&u->ring_cons_mutex);
if (file->f_flags & O_NONBLOCK)
return -EAGAIN;
@@ -141,20 +148,24 @@ static ssize_t evtchn_read(struct file *
bytes2 = count - bytes1;
}
+ rc = -EFAULT;
if (copy_to_user(buf, &u->ring[EVTCHN_RING_MASK(c)], bytes1) ||
((bytes2 != 0) &&
copy_to_user(&buf[bytes1], &u->ring[0], bytes2)))
- return -EFAULT;
+ goto unlock_out;
u->ring_cons += (bytes1 + bytes2) / sizeof(evtchn_port_t);
-
- return bytes1 + bytes2;
+ rc = bytes1 + bytes2;
+
+ unlock_out:
+ mutex_unlock(&u->ring_cons_mutex);
+ return rc;
}
static ssize_t evtchn_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
- int rc, i;
+ int rc, i;
evtchn_port_t *kbuf = (evtchn_port_t *)__get_free_page(GFP_KERNEL);
struct per_user_data *u = file->private_data;
@@ -164,18 +175,16 @@ static ssize_t evtchn_write(struct file
/* Whole number of ports. */
count &= ~(sizeof(evtchn_port_t)-1);
- if (count == 0) {
- rc = 0;
+ rc = 0;
+ if (count == 0)
goto out;
- }
if (count > PAGE_SIZE)
count = PAGE_SIZE;
- if (copy_from_user(kbuf, buf, count) != 0) {
- rc = -EFAULT;
+ rc = -EFAULT;
+ if (copy_from_user(kbuf, buf, count) != 0)
goto out;
- }
spin_lock_irq(&port_user_lock);
for (i = 0; i < (count/sizeof(evtchn_port_t)); i++)
@@ -321,9 +330,11 @@ static int evtchn_ioctl(struct inode *in
case IOCTL_EVTCHN_RESET: {
/* Initialise the ring to empty. Clear errors. */
+ mutex_lock(&u->ring_cons_mutex);
spin_lock_irq(&port_user_lock);
u->ring_cons = u->ring_prod = u->ring_overflow = 0;
spin_unlock_irq(&port_user_lock);
+ mutex_unlock(&u->ring_cons_mutex);
rc = 0;
break;
}
@@ -370,6 +381,8 @@ static int evtchn_open(struct inode *ino
kfree(u);
return -ENOMEM;
}
+
+ mutex_init(&u->ring_cons_mutex);
filp->private_data = u;
diff -r e7da2fcb7a22 -r fc9e2f7920c9
linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_capability_pm.c
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_capability_pm.c
Fri Mar 30 10:27:15 2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_capability_pm.c
Fri Mar 30 17:18:42 2007 -0600
@@ -32,19 +32,19 @@ static int pm_ctrl_write(struct pci_dev
void *data)
{
int err;
- u16 cur_value;
- pci_power_t new_state;
+ u16 old_value;
+ pci_power_t new_state, old_state;
- /* Handle setting power state separately */
- new_state = (pci_power_t)(new_value & PCI_PM_CTRL_STATE_MASK);
-
- err = pci_read_config_word(dev, offset, &cur_value);
+ err = pci_read_config_word(dev, offset, &old_value);
if (err)
goto out;
+ old_state = (pci_power_t)(old_value & PCI_PM_CTRL_STATE_MASK);
+ new_state = (pci_power_t)(new_value & PCI_PM_CTRL_STATE_MASK);
+
new_value &= PM_OK_BITS;
- if ((cur_value & PM_OK_BITS) != new_value) {
- new_value = (cur_value & ~PM_OK_BITS) | new_value;
+ if ((old_value & PM_OK_BITS) != new_value) {
+ new_value = (old_value & ~PM_OK_BITS) | new_value;
err = pci_write_config_word(dev, offset, new_value);
if (err)
goto out;
@@ -53,10 +53,25 @@ static int pm_ctrl_write(struct pci_dev
/* Let pci core handle the power management change */
dev_dbg(&dev->dev, "set power state to %x\n", new_state);
err = pci_set_power_state(dev, new_state);
- if (err)
+ if (err) {
err = PCIBIOS_SET_FAILED;
+ goto out;
+ }
- out:
+ /*
+ * Device may lose PCI config info on D3->D0 transition. This
+ * is a problem for some guests which will not reset BARs. Even
+ * those that have a go will be foiled by our BAR-write handler
+ * which will discard the write! Since Linux won't re-init
+ * the config space automatically in all cases, we do it here.
+ * Future: Should we re-initialise all first 64 bytes of config space?
+ */
+ if (new_state == PCI_D0 &&
+ (old_state == PCI_D3hot || old_state == PCI_D3cold) &&
+ !(old_value & PCI_PM_CTRL_NO_SOFT_RESET))
+ pci_restore_bars(dev);
+
+ out:
return err;
}
diff -r e7da2fcb7a22 -r fc9e2f7920c9
linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_header.c
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_header.c Fri Mar
30 10:27:15 2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_header.c Fri Mar
30 17:18:42 2007 -0600
@@ -20,11 +20,15 @@ struct pci_bar_info {
static int command_write(struct pci_dev *dev, int offset, u16 value, void
*data)
{
+ int err;
+
if (!dev->is_enabled && is_enable_cmd(value)) {
if (unlikely(verbose_request))
printk(KERN_DEBUG "pciback: %s: enable\n",
pci_name(dev));
- pci_enable_device(dev);
+ err = pci_enable_device(dev);
+ if (err)
+ return err;
} else if (dev->is_enabled && !is_enable_cmd(value)) {
if (unlikely(verbose_request))
printk(KERN_DEBUG "pciback: %s: disable\n",
@@ -44,7 +48,13 @@ static int command_write(struct pci_dev
printk(KERN_DEBUG
"pciback: %s: enable memory-write-invalidate\n",
pci_name(dev));
- pci_set_mwi(dev);
+ err = pci_set_mwi(dev);
+ if (err) {
+ printk(KERN_WARNING
+ "pciback: %s: cannot enable
memory-write-invalidate (%d)\n",
+ pci_name(dev), err);
+ value &= ~PCI_COMMAND_INVALIDATE;
+ }
}
return pci_write_config_word(dev, offset, value);
diff -r e7da2fcb7a22 -r fc9e2f7920c9
linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c Fri Mar 30
10:27:15 2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c Fri Mar 30
17:18:42 2007 -0600
@@ -805,6 +805,18 @@ static ssize_t permissive_show(struct de
DRIVER_ATTR(permissive, S_IRUSR | S_IWUSR, permissive_show, permissive_add);
+static void pcistub_exit(void)
+{
+ driver_remove_file(&pciback_pci_driver.driver, &driver_attr_new_slot);
+ driver_remove_file(&pciback_pci_driver.driver,
+ &driver_attr_remove_slot);
+ driver_remove_file(&pciback_pci_driver.driver, &driver_attr_slots);
+ driver_remove_file(&pciback_pci_driver.driver, &driver_attr_quirks);
+ driver_remove_file(&pciback_pci_driver.driver, &driver_attr_permissive);
+
+ pci_unregister_driver(&pciback_pci_driver);
+}
+
static int __init pcistub_init(void)
{
int pos = 0;
@@ -845,12 +857,23 @@ static int __init pcistub_init(void)
if (err < 0)
goto out;
- driver_create_file(&pciback_pci_driver.driver, &driver_attr_new_slot);
- driver_create_file(&pciback_pci_driver.driver,
- &driver_attr_remove_slot);
- driver_create_file(&pciback_pci_driver.driver, &driver_attr_slots);
- driver_create_file(&pciback_pci_driver.driver, &driver_attr_quirks);
- driver_create_file(&pciback_pci_driver.driver, &driver_attr_permissive);
+ err = driver_create_file(&pciback_pci_driver.driver,
+ &driver_attr_new_slot);
+ if (!err)
+ err = driver_create_file(&pciback_pci_driver.driver,
+ &driver_attr_remove_slot);
+ if (!err)
+ err = driver_create_file(&pciback_pci_driver.driver,
+ &driver_attr_slots);
+ if (!err)
+ err = driver_create_file(&pciback_pci_driver.driver,
+ &driver_attr_quirks);
+ if (!err)
+ err = driver_create_file(&pciback_pci_driver.driver,
+ &driver_attr_permissive);
+
+ if (err)
+ pcistub_exit();
out:
return err;
@@ -887,23 +910,17 @@ static int __init pciback_init(void)
#endif
pcistub_init_devices_late();
- pciback_xenbus_register();
-
- return 0;
+ err = pciback_xenbus_register();
+ if (err)
+ pcistub_exit();
+
+ return err;
}
static void __exit pciback_cleanup(void)
{
pciback_xenbus_unregister();
-
- driver_remove_file(&pciback_pci_driver.driver, &driver_attr_new_slot);
- driver_remove_file(&pciback_pci_driver.driver,
- &driver_attr_remove_slot);
- driver_remove_file(&pciback_pci_driver.driver, &driver_attr_slots);
- driver_remove_file(&pciback_pci_driver.driver, &driver_attr_quirks);
- driver_remove_file(&pciback_pci_driver.driver, &driver_attr_permissive);
-
- pci_unregister_driver(&pciback_pci_driver);
+ pcistub_exit();
}
module_init(pciback_init);
diff -r e7da2fcb7a22 -r fc9e2f7920c9
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c Fri Mar 30
10:27:15 2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c Fri Mar 30
17:18:42 2007 -0600
@@ -58,6 +58,13 @@ struct xenbus_dev_transaction {
struct xenbus_transaction handle;
};
+struct read_buffer {
+ struct list_head list;
+ unsigned int cons;
+ unsigned int len;
+ char msg[];
+};
+
struct xenbus_dev_data {
/* In-progress transaction. */
struct list_head transactions;
@@ -73,9 +80,7 @@ struct xenbus_dev_data {
} u;
/* Response queue. */
-#define MASK_READ_IDX(idx) ((idx)&(PAGE_SIZE-1))
- char read_buffer[PAGE_SIZE];
- unsigned int read_cons, read_prod;
+ struct list_head read_buffers;
wait_queue_head_t read_waitq;
struct mutex reply_mutex;
@@ -88,18 +93,34 @@ static ssize_t xenbus_dev_read(struct fi
size_t len, loff_t *ppos)
{
struct xenbus_dev_data *u = filp->private_data;
- int i;
-
- if (wait_event_interruptible(u->read_waitq,
- u->read_prod != u->read_cons))
- return -EINTR;
-
- for (i = 0; i < len; i++) {
- if (u->read_cons == u->read_prod)
- break;
- put_user(u->read_buffer[MASK_READ_IDX(u->read_cons)], ubuf+i);
- u->read_cons++;
- }
+ struct read_buffer *rb;
+ int i, ret;
+
+ mutex_lock(&u->reply_mutex);
+ while (list_empty(&u->read_buffers)) {
+ mutex_unlock(&u->reply_mutex);
+ ret = wait_event_interruptible(u->read_waitq,
+ !list_empty(&u->read_buffers));
+ if (ret)
+ return ret;
+ mutex_lock(&u->reply_mutex);
+ }
+
+ rb = list_entry(u->read_buffers.next, struct read_buffer, list);
+ for (i = 0; i < len;) {
+ put_user(rb->msg[rb->cons], ubuf + i);
+ i++;
+ rb->cons++;
+ if (rb->cons == rb->len) {
+ list_del(&rb->list);
+ kfree(rb);
+ if (list_empty(&u->read_buffers))
+ break;
+ rb = list_entry(u->read_buffers.next,
+ struct read_buffer, list);
+ }
+ }
+ mutex_unlock(&u->reply_mutex);
return i;
}
@@ -107,16 +128,20 @@ static void queue_reply(struct xenbus_de
static void queue_reply(struct xenbus_dev_data *u,
char *data, unsigned int len)
{
- int i;
-
- mutex_lock(&u->reply_mutex);
-
- for (i = 0; i < len; i++, u->read_prod++)
- u->read_buffer[MASK_READ_IDX(u->read_prod)] = data[i];
-
- BUG_ON((u->read_prod - u->read_cons) > sizeof(u->read_buffer));
-
- mutex_unlock(&u->reply_mutex);
+ struct read_buffer *rb;
+
+ if (len == 0)
+ return;
+
+ rb = kmalloc(sizeof(*rb) + len, GFP_KERNEL);
+ BUG_ON(rb == NULL);
+
+ rb->cons = 0;
+ rb->len = len;
+
+ memcpy(rb->msg, data, len);
+
+ list_add_tail(&rb->list, &u->read_buffers);
wake_up(&u->read_waitq);
}
@@ -155,10 +180,12 @@ static void watch_fired(struct xenbus_wa
hdr.type = XS_WATCH_EVENT;
hdr.len = body_len;
-
+
+ mutex_lock(&adap->dev_data->reply_mutex);
queue_reply(adap->dev_data, (char *)&hdr, sizeof(hdr));
queue_reply(adap->dev_data, (char *)path, path_len);
queue_reply(adap->dev_data, (char *)token, tok_len);
+ mutex_unlock(&adap->dev_data->reply_mutex);
}
static LIST_HEAD(watch_list);
@@ -230,13 +257,18 @@ static ssize_t xenbus_dev_write(struct f
list_del(&trans->list);
kfree(trans);
}
+ mutex_lock(&u->reply_mutex);
queue_reply(u, (char *)&u->u.msg, sizeof(u->u.msg));
queue_reply(u, (char *)reply, u->u.msg.len);
+ mutex_unlock(&u->reply_mutex);
kfree(reply);
break;
case XS_WATCH:
- case XS_UNWATCH:
+ case XS_UNWATCH: {
+ static const char *XS_RESP = "OK";
+ struct xsd_sockmsg hdr;
+
path = u->u.buffer + sizeof(u->u.msg);
token = memchr(path, 0, u->u.msg.len);
if (token == NULL) {
@@ -246,9 +278,6 @@ static ssize_t xenbus_dev_write(struct f
token++;
if (msg_type == XS_WATCH) {
- static const char * XS_WATCH_RESP = "OK";
- struct xsd_sockmsg hdr;
-
watch = kmalloc(sizeof(*watch), GFP_KERNEL);
watch->watch.node = kmalloc(strlen(path)+1,
GFP_KERNEL);
@@ -266,11 +295,6 @@ static ssize_t xenbus_dev_write(struct f
}
list_add(&watch->list, &u->watches);
-
- hdr.type = XS_WATCH;
- hdr.len = strlen(XS_WATCH_RESP) + 1;
- queue_reply(u, (char *)&hdr, sizeof(hdr));
- queue_reply(u, (char *)XS_WATCH_RESP, hdr.len);
} else {
list_for_each_entry_safe(watch, tmp_watch,
&u->watches, list) {
@@ -285,7 +309,14 @@ static ssize_t xenbus_dev_write(struct f
}
}
+ hdr.type = msg_type;
+ hdr.len = strlen(XS_RESP) + 1;
+ mutex_lock(&u->reply_mutex);
+ queue_reply(u, (char *)&hdr, sizeof(hdr));
+ queue_reply(u, (char *)XS_RESP, hdr.len);
+ mutex_unlock(&u->reply_mutex);
break;
+ }
default:
rc = -EINVAL;
@@ -312,6 +343,7 @@ static int xenbus_dev_open(struct inode
INIT_LIST_HEAD(&u->transactions);
INIT_LIST_HEAD(&u->watches);
+ INIT_LIST_HEAD(&u->read_buffers);
init_waitqueue_head(&u->read_waitq);
mutex_init(&u->reply_mutex);
@@ -349,7 +381,7 @@ static unsigned int xenbus_dev_poll(stru
struct xenbus_dev_data *u = file->private_data;
poll_wait(file, &u->read_waitq, wait);
- if (u->read_cons != u->read_prod)
+ if (!list_empty(&u->read_buffers))
return POLLIN | POLLRDNORM;
return 0;
}
diff -r e7da2fcb7a22 -r fc9e2f7920c9
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Fri Mar 30
10:27:15 2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Fri Mar 30
17:18:42 2007 -0600
@@ -335,6 +335,9 @@ int xenbus_register_driver_common(struct
{
int ret;
+ if (bus->error)
+ return bus->error;
+
drv->driver.name = drv->name;
drv->driver.bus = &bus->bus;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
@@ -476,6 +479,9 @@ int xenbus_probe_node(struct xen_bus_typ
enum xenbus_state state = xenbus_read_driver_state(nodename);
+ if (bus->error)
+ return bus->error;
+
if (state != XenbusStateInitialising) {
/* Device is not new, so ignore it. This can happen if a
device is going away after switching to Closed. */
@@ -513,10 +519,18 @@ int xenbus_probe_node(struct xen_bus_typ
if (err)
goto fail;
- device_create_file(&xendev->dev, &dev_attr_nodename);
- device_create_file(&xendev->dev, &dev_attr_devtype);
-
- return 0;
+ err = device_create_file(&xendev->dev, &dev_attr_nodename);
+ if (err)
+ goto unregister;
+ err = device_create_file(&xendev->dev, &dev_attr_devtype);
+ if (err)
+ goto unregister;
+
+ return 0;
+unregister:
+ device_remove_file(&xendev->dev, &dev_attr_nodename);
+ device_remove_file(&xendev->dev, &dev_attr_devtype);
+ device_unregister(&xendev->dev);
fail:
kfree(xendev);
return err;
@@ -564,6 +578,9 @@ int xenbus_probe_devices(struct xen_bus_
int err = 0;
char **dir;
unsigned int i, dir_n;
+
+ if (bus->error)
+ return bus->error;
dir = xenbus_directory(XBT_NIL, bus->root, "", &dir_n);
if (IS_ERR(dir))
@@ -608,7 +625,7 @@ void dev_changed(const char *node, struc
char type[BUS_ID_SIZE];
const char *p, *root;
- if (char_count(node, '/') < 2)
+ if (bus->error || char_count(node, '/') < 2)
return;
exists = xenbus_exists(XBT_NIL, node, "");
@@ -742,7 +759,8 @@ void xenbus_suspend(void)
{
DPRINTK("");
- bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev);
+ if (!xenbus_frontend.error)
+ bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev);
xenbus_backend_suspend(suspend_dev);
xs_suspend();
}
@@ -752,7 +770,8 @@ void xenbus_resume(void)
{
xb_init_comms();
xs_resume();
- bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, resume_dev);
+ if (!xenbus_frontend.error)
+ bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, resume_dev);
xenbus_backend_resume(resume_dev);
}
EXPORT_SYMBOL_GPL(xenbus_resume);
@@ -760,7 +779,8 @@ void xenbus_suspend_cancel(void)
void xenbus_suspend_cancel(void)
{
xs_suspend_cancel();
- bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_cancel_dev);
+ if (!xenbus_frontend.error)
+ bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL,
suspend_cancel_dev);
xenbus_backend_resume(suspend_cancel_dev);
}
EXPORT_SYMBOL_GPL(xenbus_suspend_cancel);
@@ -854,7 +874,11 @@ static int __init xenbus_probe_init(void
return -ENODEV;
/* Register ourselves with the kernel bus subsystem */
- bus_register(&xenbus_frontend.bus);
+ xenbus_frontend.error = bus_register(&xenbus_frontend.bus);
+ if (xenbus_frontend.error)
+ printk(KERN_WARNING
+ "XENBUS: Error registering frontend bus: %i\n",
+ xenbus_frontend.error);
xenbus_backend_bus_register();
/*
@@ -925,7 +949,15 @@ static int __init xenbus_probe_init(void
}
/* Register ourselves with the kernel device subsystem */
- device_register(&xenbus_frontend.dev);
+ if (!xenbus_frontend.error) {
+ xenbus_frontend.error = device_register(&xenbus_frontend.dev);
+ if (xenbus_frontend.error) {
+ bus_unregister(&xenbus_frontend.bus);
+ printk(KERN_WARNING
+ "XENBUS: Error registering frontend device:
%i\n",
+ xenbus_frontend.error);
+ }
+ }
xenbus_backend_device_register();
if (!is_initial_xendomain())
@@ -972,6 +1004,8 @@ static int is_disconnected_device(struct
static int exists_disconnected_device(struct device_driver *drv)
{
+ if (xenbus_frontend.error)
+ return xenbus_frontend.error;
return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv,
is_disconnected_device);
}
@@ -1036,8 +1070,10 @@ static void wait_for_devices(struct xenb
#ifndef MODULE
static int __init boot_wait_for_devices(void)
{
- ready_to_wait_for_devices = 1;
- wait_for_devices(NULL);
+ if (!xenbus_frontend.error) {
+ ready_to_wait_for_devices = 1;
+ wait_for_devices(NULL);
+ }
return 0;
}
diff -r e7da2fcb7a22 -r fc9e2f7920c9
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.h
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.h Fri Mar 30
10:27:15 2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.h Fri Mar 30
17:18:42 2007 -0600
@@ -51,6 +51,7 @@ struct xen_bus_type
struct xen_bus_type
{
char *root;
+ int error;
unsigned int levels;
int (*get_bus_id)(char bus_id[BUS_ID_SIZE], const char *nodename);
int (*probe)(const char *type, const char *dir);
diff -r e7da2fcb7a22 -r fc9e2f7920c9
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe_backend.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe_backend.c Fri Mar
30 10:27:15 2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe_backend.c Fri Mar
30 17:18:42 2007 -0600
@@ -245,13 +245,15 @@ void xenbus_backend_suspend(int (*fn)(st
void xenbus_backend_suspend(int (*fn)(struct device *, void *))
{
DPRINTK("");
- bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn);
+ if (!xenbus_backend.error)
+ bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn);
}
void xenbus_backend_resume(int (*fn)(struct device *, void *))
{
DPRINTK("");
- bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn);
+ if (!xenbus_backend.error)
+ bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn);
}
void xenbus_backend_probe_and_watch(void)
@@ -262,10 +264,23 @@ void xenbus_backend_probe_and_watch(void
void xenbus_backend_bus_register(void)
{
- bus_register(&xenbus_backend.bus);
+ xenbus_backend.error = bus_register(&xenbus_backend.bus);
+ if (xenbus_backend.error)
+ printk(KERN_WARNING
+ "XENBUS: Error registering backend bus: %i\n",
+ xenbus_backend.error);
}
void xenbus_backend_device_register(void)
{
- device_register(&xenbus_backend.dev);
-}
+ if (xenbus_backend.error)
+ return;
+
+ xenbus_backend.error = device_register(&xenbus_backend.dev);
+ if (xenbus_backend.error) {
+ bus_unregister(&xenbus_backend.bus);
+ printk(KERN_WARNING
+ "XENBUS: Error registering backend device: %i\n",
+ xenbus_backend.error);
+ }
+}
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/Rules.mk
--- a/tools/Rules.mk Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/Rules.mk Fri Mar 30 17:18:42 2007 -0600
@@ -24,9 +24,9 @@ CFLAGS += $(CFLAGS-y)
CFLAGS += $(CFLAGS-y)
# Require GCC v3.4+ (to avoid issues with alignment constraints in Xen headers)
-ifeq ($(CONFIG_X86)$(call cc-ver,$(CC),0x030400),yn)
-$(error Xen tools require at least gcc-3.4)
-endif
+check-$(CONFIG_X86) = $(call cc-ver-check,CC,0x030400,\
+ "Xen requires at least gcc-3.4")
+$(eval $(check-y))
%.opic: %.c
$(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $<
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/examples/Makefile
--- a/tools/examples/Makefile Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/examples/Makefile Fri Mar 30 17:18:42 2007 -0600
@@ -9,7 +9,9 @@ XENDOMAINS_SYSCONFIG = init.d/sysconfig.
# Xen configuration dir and configs to go there.
XEN_CONFIG_DIR = /etc/xen
XEN_CONFIGS = xend-config.sxp
+XEN_CONFIGS += xend-config-xenapi.sxp
XEN_CONFIGS += xm-config.xml
+XEN_CONFIGS += xm-config-xenapi.xml
XEN_CONFIGS += xmexample1
XEN_CONFIGS += xmexample2
XEN_CONFIGS += xmexample.hvm
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/examples/xend-config-xenapi.sxp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/examples/xend-config-xenapi.sxp Fri Mar 30 17:18:42 2007 -0600
@@ -0,0 +1,195 @@
+# -*- sh -*-
+
+#
+# Xend configuration file.
+#
+
+# This example configuration is appropriate for an installation that
+# utilizes a bridged network configuration. Access to xend via http
+# is disabled.
+
+# Commented out entries show the default for that entry, unless otherwise
+# specified.
+
+#(logfile /var/log/xen/xend.log)
+#(loglevel DEBUG)
+
+
+# The Xen-API server configuration. (Please note that this server is
+# available as an UNSUPPORTED PREVIEW in Xen 3.0.4, and should not be relied
+# upon).
+#
+# This value configures the ports, interfaces, and access controls for the
+# Xen-API server. Each entry in the list starts with either unix, a port
+# number, or an address:port pair. If this is "unix", then a UDP socket is
+# opened, and this entry applies to that. If it is a port, then Xend will
+# listen on all interfaces on that TCP port, and if it is an address:port
+# pair, then Xend will listen on the specified port, using the interface with
+# the specified address.
+#
+# The subsequent string configures the user-based access control for the
+# listener in question. This can be one of "none" or "pam", indicating either
+# that users should be allowed access unconditionally, or that the local
+# Pluggable Authentication Modules configuration should be used. If this
+# string is missing or empty, then "pam" is used.
+#
+# The final string gives the host-based access control for that listener. If
+# this is missing or empty, then all connections are accepted. Otherwise,
+# this should be a space-separated sequence of regular expressions; any host
+# with a fully-qualified domain name or an IP address that matches one of
+# these regular expressions will be accepted.
+#
+# Example: listen on TCP port 9363 on all interfaces, accepting connections
+# only from machines in example.com or localhost, and allow access through
+# the unix domain socket unconditionally:
+#
+ (xen-api-server ((9363 none)))
+# (unix none)))
+#
+# Optionally, the TCP Xen-API server can use SSL by specifying the private
+# key and certificate location:
+#
+# (9367 pam '' /etc/xen/xen-api.key /etc/xen/xen-api.crt)
+#
+# Default:
+# (xen-api-server ((unix)))
+
+
+#(xend-http-server no)
+#(xend-unix-server no)
+#(xend-tcp-xmlrpc-server no)
+#(xend-unix-xmlrpc-server yes)
+#(xend-relocation-server no)
+(xend-relocation-server yes)
+
+#(xend-unix-path /var/lib/xend/xend-socket)
+
+
+# Address and port xend should use for the legacy TCP XMLRPC interface,
+# if xen-tcp-xmlrpc-server is set.
+#(xen-tcp-xmlrpc-server-address 'localhost')
+#(xen-tcp-xmlrpc-server-port 8006)
+
+# SSL key and certificate to use for the legacy TCP XMLRPC interface.
+# Setting these will mean that this port serves only SSL connections as
+# opposed to plaintext ones.
+#(xend-tcp-xmlrpc-server-ssl-key-file /etc/xen/xmlrpc.key)
+#(xend-tcp-xmlrpc-server-ssl-cert-file /etc/xen/xmlrpc.crt)
+
+
+# Port xend should use for the HTTP interface, if xend-http-server is set.
+#(xend-port 8000)
+
+# Port xend should use for the relocation interface, if xend-relocation-server
+# is set.
+#(xend-relocation-port 8002)
+
+# Address xend should listen on for HTTP connections, if xend-http-server is
+# set.
+# Specifying 'localhost' prevents remote connections.
+# Specifying the empty string '' (the default) allows all connections.
+#(xend-address '')
+#(xend-address localhost)
+
+# Address xend should listen on for relocation-socket connections, if
+# xend-relocation-server is set.
+# Meaning and default as for xend-address above.
+#(xend-relocation-address '')
+
+# The hosts allowed to talk to the relocation port. If this is empty (the
+# default), then all connections are allowed (assuming that the connection
+# arrives on a port and interface on which we are listening; see
+# xend-relocation-port and xend-relocation-address above). Otherwise, this
+# should be a space-separated sequence of regular expressions. Any host with
+# a fully-qualified domain name or an IP address that matches one of these
+# regular expressions will be accepted.
+#
+# For example:
+# (xend-relocation-hosts-allow '^localhost$ ^.*\\.example\\.org$')
+#
+#(xend-relocation-hosts-allow '')
+(xend-relocation-hosts-allow '^localhost$ ^localhost\\.localdomain$')
+
+# The limit (in kilobytes) on the size of the console buffer
+#(console-limit 1024)
+
+##
+# To bridge network traffic, like this:
+#
+# dom0: fake eth0 -> vif0.0 -+
+# |
+# bridge -> real eth0 -> the network
+# |
+# domU: fake eth0 -> vifN.0 -+
+#
+# use
+#
+# (network-script network-bridge)
+#
+# Your default ethernet device is used as the outgoing interface, by default.
+# To use a different one (e.g. eth1) use
+#
+# (network-script 'network-bridge netdev=eth1')
+#
+# The bridge is named xenbr0, by default. To rename the bridge, use
+#
+# (network-script 'network-bridge bridge=<name>')
+#
+# It is possible to use the network-bridge script in more complicated
+# scenarios, such as having two outgoing interfaces, with two bridges, and
+# two fake interfaces per guest domain. To do things like this, write
+# yourself a wrapper script, and call network-bridge from it, as appropriate.
+#
+(network-script network-bridge)
+
+# The script used to control virtual interfaces. This can be overridden on a
+# per-vif basis when creating a domain or a configuring a new vif. The
+# vif-bridge script is designed for use with the network-bridge script, or
+# similar configurations.
+#
+# If you have overridden the bridge name using
+# (network-script 'network-bridge bridge=<name>') then you may wish to do the
+# same here. The bridge name can also be set when creating a domain or
+# configuring a new vif, but a value specified here would act as a default.
+#
+# If you are using only one bridge, the vif-bridge script will discover that,
+# so there is no need to specify it explicitly.
+#
+(vif-script vif-bridge)
+
+
+## Use the following if network traffic is routed, as an alternative to the
+# settings for bridged networking given above.
+#(network-script network-route)
+#(vif-script vif-route)
+
+
+## Use the following if network traffic is routed with NAT, as an alternative
+# to the settings for bridged networking given above.
+#(network-script network-nat)
+#(vif-script vif-nat)
+
+
+# Dom0 will balloon out when needed to free memory for domU.
+# dom0-min-mem is the lowest memory level (in MB) dom0 will get down to.
+# If dom0-min-mem=0, dom0 will never balloon out.
+(dom0-min-mem 196)
+
+# In SMP system, dom0 will use dom0-cpus # of CPUS
+# If dom0-cpus = 0, dom0 will take all cpus available
+(dom0-cpus 0)
+
+# Whether to enable core-dumps when domains crash.
+#(enable-dump no)
+
+# The tool used for initiating virtual TPM migration
+#(external-migration-tool '')
+
+# The interface for VNC servers to listen on. Defaults
+# to 127.0.0.1 To restore old 'listen everywhere' behaviour
+# set this to 0.0.0.0
+#(vnc-listen '127.0.0.1')
+
+# The default password for VNC console on HVM domain.
+# Empty string is no authentication.
+(vncpasswd '')
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/examples/xend-config.sxp
--- a/tools/examples/xend-config.sxp Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/examples/xend-config.sxp Fri Mar 30 17:18:42 2007 -0600
@@ -46,6 +46,11 @@
# (xen-api-server ((9363 pam '^localhost$ example\\.com$')
# (unix none)))
#
+# Optionally, the TCP Xen-API server can use SSL by specifying the private
+# key and certificate location:
+#
+# (9367 pam '' /etc/xen/xen-api.key /etc/xen/xen-api.crt)
+#
# Default:
# (xen-api-server ((unix)))
@@ -59,10 +64,17 @@
#(xend-unix-path /var/lib/xend/xend-socket)
-# Address and port xend should use for the TCP XMLRPC interface,
+
+# Address and port xend should use for the legacy TCP XMLRPC interface,
# if xen-tcp-xmlrpc-server is set.
#(xen-tcp-xmlrpc-server-address 'localhost')
#(xen-tcp-xmlrpc-server-port 8006)
+
+# SSL key and certificate to use for the legacy TCP XMLRPC interface.
+# Setting these will mean that this port serves only SSL connections as
+# opposed to plaintext ones.
+#(xend-tcp-xmlrpc-server-ssl-key-file /etc/xen/xmlrpc.key)
+#(xend-tcp-xmlrpc-server-ssl-cert-file /etc/xen/xmlrpc.crt)
# Port xend should use for the HTTP interface, if xend-http-server is set.
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/examples/xm-config-xenapi.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/examples/xm-config-xenapi.xml Fri Mar 30 17:18:42 2007 -0600
@@ -0,0 +1,43 @@
+<!--
+
+Copyright (C) 2006 XenSource Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of version 2.1 of the GNU Lesser General Public
+License as published by the Free Software Foundation.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+-->
+
+<!--
+
+This is a configuration file for xm; it should be placed in
+/etc/xen/xm-config.xml. If this file is missing, then xm will fall back to
+the normal behaviour that's in Xen 3.0.4 and below. The settings here are
+most useful for experimenting with the Xen-API preview in Xen 3.0.4.
+
+-->
+
+<xm>
+ <!-- The server element describes how to talk to Xend. The type may be
+ Xen-API or LegacyXMLRPC (the default). The URI is that of the
+ server; you might try http://server:9363/ or
+ httpu:///var/run/xend/xen-api.sock for the Xen-API, or
+ httpu:///var/run/xend/xmlrpc.sock for the legacy server.
+
+ The username and password attributes will be used to log in if Xen-API
+ is being used.
+ -->
+ <server type='Xen-API'
+ uri='http://localhost:9363/'
+ username='me'
+ password='mypassword' />
+</xm>
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/ioemu/hw/ne2000.c
--- a/tools/ioemu/hw/ne2000.c Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/ioemu/hw/ne2000.c Fri Mar 30 17:18:42 2007 -0600
@@ -770,7 +770,7 @@ void isa_ne2000_init(int base, int irq,
s->macaddr[4],
s->macaddr[5]);
- register_savevm("ne2000", 0, 2, ne2000_save, ne2000_load, s);
+ register_savevm("ne2000", base, 2, ne2000_save, ne2000_load, s);
}
/***********************************************************/
@@ -806,6 +806,7 @@ void pci_ne2000_init(PCIBus *bus, NICInf
PCINE2000State *d;
NE2000State *s;
uint8_t *pci_conf;
+ int instance;
d = (PCINE2000State *)pci_register_device(bus,
"NE2000", sizeof(PCINE2000State),
@@ -840,8 +841,8 @@ void pci_ne2000_init(PCIBus *bus, NICInf
s->macaddr[4],
s->macaddr[5]);
- /* XXX: instance number ? */
- register_savevm("ne2000", 0, 2, ne2000_save, ne2000_load, s);
- register_savevm("ne2000_pci", 0, 1, generic_pci_save, generic_pci_load,
- &d->dev);
-}
+ instance = pci_bus_num(bus) << 8 | s->pci_dev->devfn;
+ register_savevm("ne2000", instance, 2, ne2000_save, ne2000_load, s);
+ register_savevm("ne2000_pci", instance, 1, generic_pci_save,
+ generic_pci_load, &d->dev);
+}
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/ioemu/hw/pcnet.c
--- a/tools/ioemu/hw/pcnet.c Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/ioemu/hw/pcnet.c Fri Mar 30 17:18:42 2007 -0600
@@ -1727,10 +1727,63 @@ static void pcnet_mmio_map(PCIDevice *pc
cpu_register_physical_memory(addr, PCNET_PNPMMIO_SIZE, d->mmio_io_addr);
}
+
+static void pcnet_save(QEMUFile *f, void *opaque)
+{
+ PCNetState *s = opaque;
+ unsigned int i;
+
+ qemu_put_be32s(f, &s->rap);
+ qemu_put_be32s(f, &s->isr);
+ qemu_put_be32s(f, &s->lnkst);
+ qemu_put_be32s(f, &s->rdra);
+ qemu_put_be32s(f, &s->tdra);
+ qemu_put_buffer(f, s->prom, 16);
+ for (i = 0; i < 128; i++)
+ qemu_put_be16s(f, &s->csr[i]);
+ for (i = 0; i < 32; i++)
+ qemu_put_be16s(f, &s->bcr[i]);
+ qemu_put_be64s(f, &s->timer);
+ qemu_put_be32s(f, &s->xmit_pos);
+ qemu_put_be32s(f, &s->recv_pos);
+ qemu_put_buffer(f, s->buffer, 4096);
+ qemu_put_be32s(f, &s->tx_busy);
+ qemu_put_timer(f, s->poll_timer);
+}
+
+static int pcnet_load(QEMUFile *f, void *opaque, int version_id)
+{
+ PCNetState *s = opaque;
+ int i, ret;
+
+ if (version_id != 1)
+ return -EINVAL;
+
+ qemu_get_be32s(f, &s->rap);
+ qemu_get_be32s(f, &s->isr);
+ qemu_get_be32s(f, &s->lnkst);
+ qemu_get_be32s(f, &s->rdra);
+ qemu_get_be32s(f, &s->tdra);
+ qemu_get_buffer(f, s->prom, 16);
+ for (i = 0; i < 128; i++)
+ qemu_get_be16s(f, &s->csr[i]);
+ for (i = 0; i < 32; i++)
+ qemu_get_be16s(f, &s->bcr[i]);
+ qemu_get_be64s(f, &s->timer);
+ qemu_get_be32s(f, &s->xmit_pos);
+ qemu_get_be32s(f, &s->recv_pos);
+ qemu_get_buffer(f, s->buffer, 4096);
+ qemu_get_be32s(f, &s->tx_busy);
+ qemu_get_timer(f, s->poll_timer);
+
+ return 0;
+}
+
void pci_pcnet_init(PCIBus *bus, NICInfo *nd)
{
PCNetState *d;
uint8_t *pci_conf;
+ int instance;
#if 0
printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n",
@@ -1775,6 +1828,11 @@ void pci_pcnet_init(PCIBus *bus, NICInfo
d->vc = qemu_new_vlan_client(nd->vlan, pcnet_receive,
pcnet_can_receive, d);
+
+ instance = pci_bus_num(bus) << 8 | d->dev.devfn;
+ register_savevm("pcnet", instance, 1, pcnet_save, pcnet_load, d);
+ register_savevm("pcnet_pci", instance, 1, generic_pci_save,
+ generic_pci_load, &d->dev);
snprintf(d->vc->info_str, sizeof(d->vc->info_str),
"pcnet macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/ioemu/hw/piix4acpi.c
--- a/tools/ioemu/hw/piix4acpi.c Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/ioemu/hw/piix4acpi.c Fri Mar 30 17:18:42 2007 -0600
@@ -57,6 +57,20 @@ typedef struct PCIAcpiState {
uint16_t pm1_control; /* pm1a_ECNT_BLK */
} PCIAcpiState;
+static void piix4acpi_save(QEMUFile *f, void *opaque)
+{
+ PCIAcpiState *s = opaque;
+ qemu_put_be16s(f, &s->pm1_control);
+}
+
+static int piix4acpi_load(QEMUFile *f, void *opaque, int version_id)
+{
+ PCIAcpiState *s = opaque;
+ if (version_id > 1)
+ return -EINVAL;
+ qemu_get_be16s(f, &s->pm1_control);
+}
+
static void acpiPm1Control_writeb(void *opaque, uint32_t addr, uint32_t val)
{
PCIAcpiState *s = opaque;
@@ -193,4 +207,8 @@ void pci_piix4_acpi_init(PCIBus *bus, in
d->pm1_control = SCI_EN;
acpi_map(d, 0, 0x1f40, 0x10, PCI_ADDRESS_SPACE_IO);
-}
+
+ register_savevm("piix4acpi", 0, 1, piix4acpi_save, piix4acpi_load, d);
+ register_savevm("piix4acpi_pci", 0, 1, generic_pci_save, generic_pci_load,
+ &d->dev);
+}
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/ioemu/hw/rtl8139.c
--- a/tools/ioemu/hw/rtl8139.c Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/ioemu/hw/rtl8139.c Fri Mar 30 17:18:42 2007 -0600
@@ -3406,6 +3406,7 @@ void pci_rtl8139_init(PCIBus *bus, NICIn
PCIRTL8139State *d;
RTL8139State *s;
uint8_t *pci_conf;
+ int instance;
d = (PCIRTL8139State *)pci_register_device(bus,
"RTL8139",
sizeof(PCIRTL8139State),
@@ -3460,10 +3461,10 @@ void pci_rtl8139_init(PCIBus *bus, NICIn
s->cplus_txbuffer_len = 0;
s->cplus_txbuffer_offset = 0;
- /* XXX: instance number ? */
- register_savevm("rtl8139", 0, 2, rtl8139_save, rtl8139_load, s);
- register_savevm("rtl8139_pci", 0, 1, generic_pci_save, generic_pci_load,
- &d->dev);
+ instance = pci_bus_num(bus) << 8 | s->pci_dev->devfn;
+ register_savevm("rtl8139", instance, 2, rtl8139_save, rtl8139_load, s);
+ register_savevm("rtl8139_pci", instance, 1, generic_pci_save,
+ generic_pci_load, &d->dev);
#if RTL8139_ONBOARD_TIMER
s->timer = qemu_new_timer(vm_clock, rtl8139_timer, s);
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/ioemu/hw/usb-uhci.c
--- a/tools/ioemu/hw/usb-uhci.c Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/ioemu/hw/usb-uhci.c Fri Mar 30 17:18:42 2007 -0600
@@ -700,6 +700,7 @@ int uhci_usb_load(QEMUFile *f, void *opa
qemu_get_timer(f, s->frame_timer);
+ return 0;
}
void usb_uhci_init(PCIBus *bus, int devfn)
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/ioemu/vl.c Fri Mar 30 17:18:42 2007 -0600
@@ -6109,10 +6109,9 @@ int main(int argc, char **argv)
#endif /* !CONFIG_DM */
cyls = heads = secs = 0;
translation = BIOS_ATA_TRANSLATION_AUTO;
- pstrcpy(monitor_device, sizeof(monitor_device), "vc");
-
- pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
- for(i = 1; i < MAX_SERIAL_PORTS; i++)
+ pstrcpy(monitor_device, sizeof(monitor_device), "null");
+
+ for(i = 0; i < MAX_SERIAL_PORTS; i++)
serial_devices[i][0] = '\0';
serial_device_index = 0;
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/libxc/xc_hvm_restore.c
--- a/tools/libxc/xc_hvm_restore.c Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/libxc/xc_hvm_restore.c Fri Mar 30 17:18:42 2007 -0600
@@ -81,7 +81,7 @@ int xc_hvm_restore(int xc_handle, int io
unsigned int rc = 1, n, i;
uint32_t rec_len, nr_vcpus;
uint8_t *hvm_buf = NULL;
- unsigned long long v_end, memsize;
+ unsigned long long v_end;
unsigned long shared_page_nr;
unsigned long pfn;
@@ -91,16 +91,19 @@ int xc_hvm_restore(int xc_handle, int io
/* Types of the pfns in the current region */
unsigned long region_pfn_type[MAX_BATCH_SIZE];
- /* Number of pages of memory the guest has. *Not* the same as max_pfn. */
- unsigned long nr_pages;
-
/* The size of an array big enough to contain all guest pfns */
unsigned long pfn_array_size = max_pfn + 1;
- /* hvm guest mem size (Mb) */
- memsize = (unsigned long long)*store_mfn;
- v_end = memsize << 20;
- nr_pages = (unsigned long) memsize << (20 - PAGE_SHIFT);
+ /* Number of pages of memory the guest has. *Not* the same as max_pfn. */
+ unsigned long nr_pages = max_pfn + 1;
+ /* MMIO hole doesn't contain RAM */
+ if ( nr_pages >= HVM_BELOW_4G_MMIO_START >> PAGE_SHIFT )
+ nr_pages -= HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT;
+ /* VGA hole doesn't contain RAM */
+ nr_pages -= 0x20;
+
+ /* XXX: Unlikely to be true, but matches previous behaviour. :( */
+ v_end = (nr_pages + 0x20) << PAGE_SHIFT;
DPRINTF("xc_hvm_restore:dom=%d, nr_pages=0x%lx, store_evtchn=%d, "
"*store_mfn=%ld, pae=%u, apic=%u.\n",
@@ -146,7 +149,7 @@ int xc_hvm_restore(int xc_handle, int io
0, 0, &pfns[0x00]);
if ( (rc == 0) && (nr_pages > 0xc0) )
rc = xc_domain_memory_populate_physmap(
- xc_handle, dom, nr_pages - 0xc0, 0, 0, &pfns[0xc0]);
+ xc_handle, dom, nr_pages - 0xa0, 0, 0, &pfns[0xc0]);
if ( rc != 0 )
{
PERROR("Could not allocate memory for HVM guest.\n");
@@ -276,14 +279,6 @@ int xc_hvm_restore(int xc_handle, int io
else
shared_page_nr = (v_end >> PAGE_SHIFT) - 1;
- /* Paranoia: clean pages. */
- if ( xc_clear_domain_page(xc_handle, dom, shared_page_nr) ||
- xc_clear_domain_page(xc_handle, dom, shared_page_nr-1) ||
- xc_clear_domain_page(xc_handle, dom, shared_page_nr-2) ) {
- ERROR("error clearing comms frames!\n");
- goto out;
- }
-
xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_PFN, shared_page_nr-1);
xc_set_hvm_param(xc_handle, dom, HVM_PARAM_BUFIOREQ_PFN, shared_page_nr-2);
xc_set_hvm_param(xc_handle, dom, HVM_PARAM_IOREQ_PFN, shared_page_nr);
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/libxen/Makefile
--- a/tools/libxen/Makefile Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/libxen/Makefile Fri Mar 30 17:18:42 2007 -0600
@@ -51,6 +51,9 @@ test/test_bindings: test/test_bindings.o
test/test_bindings: test/test_bindings.o libxenapi.so
$(CC) $(LDFLAGS) -o $@ $< -L . -lxenapi
+test/test_event_handling: test/test_event_handling.o libxenapi.so
+ $(CC) $(LDFLAGS) -o $@ $< -L . -lxenapi
+
test/test_hvm_bindings: test/test_hvm_bindings.o libxenapi.so
$(CC) $(LDFLAGS) -o $@ $< -L . -lxenapi
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/libxen/include/xen_event.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/include/xen_event.h Fri Mar 30 17:18:42 2007 -0600
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2006-2007, XenSource Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef XEN_EVENT_H
+#define XEN_EVENT_H
+
+#include "xen_common.h"
+#include "xen_event_decl.h"
+#include "xen_event_operation.h"
+#include "xen_string_set.h"
+
+
+/*
+ * The event class.
+ *
+ * Asynchronous event registration and handling.
+ */
+
+
+
+typedef struct xen_event_record
+{
+ int64_t id;
+ time_t timestamp;
+ char *class;
+ enum xen_event_operation operation;
+ char *ref;
+ char *obj_uuid;
+} xen_event_record;
+
+/**
+ * Allocate a xen_event_record.
+ */
+extern xen_event_record *
+xen_event_record_alloc(void);
+
+/**
+ * Free the given xen_event_record, and all referenced values. The
+ * given record must have been allocated by this library.
+ */
+extern void
+xen_event_record_free(xen_event_record *record);
+
+
+typedef struct xen_event_record_set
+{
+ size_t size;
+ xen_event_record *contents[];
+} xen_event_record_set;
+
+/**
+ * Allocate a xen_event_record_set of the given size.
+ */
+extern xen_event_record_set *
+xen_event_record_set_alloc(size_t size);
+
+/**
+ * Free the given xen_event_record_set, and all referenced values. The
+ * given set must have been allocated by this library.
+ */
+extern void
+xen_event_record_set_free(xen_event_record_set *set);
+
+
+/**
+ * Registers this session with the event system. Specifying the empty
+ * list will register for all classes.
+ */
+extern bool
+xen_event_register(xen_session *session, struct xen_string_set *classes);
+
+
+/**
+ * Unregisters this session with the event system.
+ */
+extern bool
+xen_event_unregister(xen_session *session, struct xen_string_set *classes);
+
+
+/**
+ * Blocking call which returns a (possibly empty) batch of events.
+ */
+extern bool
+xen_event_next(xen_session *session, struct xen_event_record_set **result);
+
+
+#endif
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/libxen/include/xen_event_decl.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/include/xen_event_decl.h Fri Mar 30 17:18:42 2007 -0600
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2006-2007, XenSource Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef XEN_EVENT_DECL_H
+#define XEN_EVENT_DECL_H
+
+struct xen_event_record;
+struct xen_event_record_set;
+
+#endif
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/libxen/include/xen_event_operation.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/include/xen_event_operation.h Fri Mar 30 17:18:42
2007 -0600
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2006-2007, XenSource Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef XEN_EVENT_OPERATION_H
+#define XEN_EVENT_OPERATION_H
+
+
+#include "xen_common.h"
+
+
+enum xen_event_operation
+{
+ /**
+ * An object has been created
+ */
+ XEN_EVENT_OPERATION_ADD,
+
+ /**
+ * An object has been deleted
+ */
+ XEN_EVENT_OPERATION_DEL,
+
+ /**
+ * An object has been modified
+ */
+ XEN_EVENT_OPERATION_MOD
+};
+
+
+typedef struct xen_event_operation_set
+{
+ size_t size;
+ enum xen_event_operation contents[];
+} xen_event_operation_set;
+
+/**
+ * Allocate a xen_event_operation_set of the given size.
+ */
+extern xen_event_operation_set *
+xen_event_operation_set_alloc(size_t size);
+
+/**
+ * Free the given xen_event_operation_set. The given set must have
+ * been allocated by this library.
+ */
+extern void
+xen_event_operation_set_free(xen_event_operation_set *set);
+
+
+/**
+ * Return the name corresponding to the given code. This string must
+ * not be modified or freed.
+ */
+extern const char *
+xen_event_operation_to_string(enum xen_event_operation val);
+
+
+/**
+ * Return the correct code for the given string, or set the session
+ * object to failure and return an undefined value if the given string does
+ * not match a known code.
+ */
+extern enum xen_event_operation
+xen_event_operation_from_string(xen_session *session, const char *str);
+
+
+#endif
diff -r e7da2fcb7a22 -r fc9e2f7920c9
tools/libxen/include/xen_event_operation_internal.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/include/xen_event_operation_internal.h Fri Mar 30
17:18:42 2007 -0600
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2006-2007, XenSource Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+/*
+ * Declarations of the abstract types used during demarshalling of enum
+ * xen_event_operation. Internal to this library -- do not use from outside.
+ */
+
+
+#ifndef XEN_EVENT_OPERATION_INTERNAL_H
+#define XEN_EVENT_OPERATION_INTERNAL_H
+
+
+#include "xen_internal.h"
+
+
+extern const abstract_type xen_event_operation_abstract_type_;
+extern const abstract_type xen_event_operation_set_abstract_type_;
+
+
+#endif
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/libxen/include/xen_network.h
--- a/tools/libxen/include/xen_network.h Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/libxen/include/xen_network.h Fri Mar 30 17:18:42 2007 -0600
@@ -22,6 +22,7 @@
#include "xen_common.h"
#include "xen_network_decl.h"
#include "xen_pif_decl.h"
+#include "xen_string_string_map.h"
#include "xen_vif_decl.h"
@@ -68,6 +69,7 @@ typedef struct xen_network_record
char *name_description;
struct xen_vif_record_opt_set *vifs;
struct xen_pif_record_opt_set *pifs;
+ xen_string_string_map *other_config;
} xen_network_record;
/**
@@ -220,6 +222,13 @@ xen_network_get_pifs(xen_session *sessio
/**
+ * Get the other_config field of the given network.
+ */
+extern bool
+xen_network_get_other_config(xen_session *session, xen_string_string_map
**result, xen_network network);
+
+
+/**
* Set the name/label field of the given network.
*/
extern bool
@@ -234,6 +243,30 @@ xen_network_set_name_description(xen_ses
/**
+ * Set the other_config field of the given network.
+ */
+extern bool
+xen_network_set_other_config(xen_session *session, xen_network network,
xen_string_string_map *other_config);
+
+
+/**
+ * Add the given key-value pair to the other_config field of the given
+ * network.
+ */
+extern bool
+xen_network_add_to_other_config(xen_session *session, xen_network network,
char *key, char *value);
+
+
+/**
+ * Remove the given key and its corresponding value from the
+ * other_config field of the given network. If the key is not in that Map,
+ * then do nothing.
+ */
+extern bool
+xen_network_remove_from_other_config(xen_session *session, xen_network
network, char *key);
+
+
+/**
* Return a list of all the networks known to the system.
*/
extern bool
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/libxen/src/xen_common.c
--- a/tools/libxen/src/xen_common.c Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/libxen/src/xen_common.c Fri Mar 30 17:18:42 2007 -0600
@@ -1217,11 +1217,88 @@ static void parse_result(xen_session *se
}
+static void
+make_body_add_type(enum abstract_typename typename, abstract_value *v,
+ xmlNode *params_node)
+{
+ char buf[20];
+ switch (typename)
+ {
+ case STRING:
+ add_param(params_node, "string", v->u.string_val);
+ break;
+
+ case INT:
+ snprintf(buf, sizeof(buf), "%"PRId64, v->u.int_val);
+ add_param(params_node, "string", buf);
+ break;
+
+ case FLOAT:
+ snprintf(buf, sizeof(buf), "%lf", v->u.float_val);
+ add_param(params_node, "double", buf);
+ break;
+
+ case BOOL:
+ add_param(params_node, "boolean", v->u.bool_val ? "1" : "0");
+ break;
+
+ case VOID:
+ add_param(params_node, "string", "");
+ break;
+
+ case ENUM:
+ add_param(params_node, "string",
+ v->type->enum_marshaller(v->u.enum_val));
+ break;
+
+ case SET:
+ {
+ const struct abstract_type *member_type = v->type->child;
+ arbitrary_set *set_val = v->u.struct_val;
+ abstract_value v;
+ xmlNode *data_node = add_param_struct(params_node);
+
+ for (size_t i = 0; i < set_val->size; i++)
+ {
+ switch (member_type->typename) {
+ case STRING:
+ v.u.string_val = (char *)set_val->contents[i];
+ make_body_add_type(member_type->typename, &v, data_node);
+ break;
+ default:
+ assert(false);
+ }
+ }
+ }
+ break;
+
+ case STRUCT:
+ {
+ size_t member_count = v->type->member_count;
+
+ xmlNode *struct_node = add_param_struct(params_node);
+
+ for (size_t i = 0; i < member_count; i++)
+ {
+ const struct struct_member *mem = v->type->members + i;
+ const char *key = mem->key;
+ void *struct_value = v->u.struct_val;
+
+ add_struct_value(mem->type, struct_value + mem->offset,
+ add_struct_member, key, struct_node);
+ }
+ }
+ break;
+
+ default:
+ assert(false);
+ }
+}
+
+
static char *
make_body(const char *method_name, abstract_value params[], int param_count)
{
- char buf[20];
-
xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0");
xmlNode *methodCall = xmlNewNode(NULL, BAD_CAST "methodCall");
xmlDocSetRootElement(doc, methodCall);
@@ -1235,56 +1312,7 @@ make_body(const char *method_name, abstr
for (int p = 0; p < param_count; p++)
{
abstract_value *v = params + p;
- switch (v->type->typename)
- {
- case STRING:
- add_param(params_node, "string", v->u.string_val);
- break;
-
- case INT:
- snprintf(buf, sizeof(buf), "%"PRId64, v->u.int_val);
- add_param(params_node, "string", buf);
- break;
-
- case FLOAT:
- snprintf(buf, sizeof(buf), "%lf", v->u.float_val);
- add_param(params_node, "double", buf);
- break;
-
- case BOOL:
- add_param(params_node, "boolean", v->u.bool_val ? "1" : "0");
- break;
-
- case VOID:
- add_param(params_node, "string", "");
- break;
-
- case ENUM:
- add_param(params_node, "string",
- v->type->enum_marshaller(v->u.enum_val));
- break;
-
- case STRUCT:
- {
- size_t member_count = v->type->member_count;
-
- xmlNode *struct_node = add_param_struct(params_node);
-
- for (size_t i = 0; i < member_count; i++)
- {
- const struct struct_member *mem = v->type->members + i;
- const char *key = mem->key;
- void *struct_value = v->u.struct_val;
-
- add_struct_value(mem->type, struct_value + mem->offset,
- add_struct_member, key, struct_node);
- }
- }
- break;
-
- default:
- assert(false);
- }
+ make_body_add_type(v->type->typename, v, params_node);
}
xmlBufferPtr buffer = xmlBufferCreate();
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/libxen/src/xen_event.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/src/xen_event.c Fri Mar 30 17:18:42 2007 -0600
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2006-2007, XenSource Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#include "xen_common.h"
+#include "xen_event.h"
+#include "xen_event_operation_internal.h"
+#include "xen_internal.h"
+
+
+XEN_ALLOC(xen_event_record)
+XEN_SET_ALLOC_FREE(xen_event_record)
+
+
+static const struct_member xen_event_record_struct_members[] =
+ {
+ { .key = "id",
+ .type = &abstract_type_int,
+ .offset = offsetof(xen_event_record, id) },
+ { .key = "timestamp",
+ .type = &abstract_type_datetime,
+ .offset = offsetof(xen_event_record, timestamp) },
+ { .key = "class",
+ .type = &abstract_type_string,
+ .offset = offsetof(xen_event_record, class) },
+ { .key = "operation",
+ .type = &xen_event_operation_abstract_type_,
+ .offset = offsetof(xen_event_record, operation) },
+ { .key = "ref",
+ .type = &abstract_type_string,
+ .offset = offsetof(xen_event_record, ref) },
+ { .key = "obj_uuid",
+ .type = &abstract_type_string,
+ .offset = offsetof(xen_event_record, obj_uuid) }
+ };
+
+const abstract_type xen_event_record_abstract_type_ =
+ {
+ .typename = STRUCT,
+ .struct_size = sizeof(xen_event_record),
+ .member_count =
+ sizeof(xen_event_record_struct_members) / sizeof(struct_member),
+ .members = xen_event_record_struct_members
+ };
+
+
+const abstract_type xen_event_record_set_abstract_type_ =
+ {
+ .typename = SET,
+ .child = &xen_event_record_abstract_type_
+ };
+
+
+void
+xen_event_record_free(xen_event_record *record)
+{
+ if (record == NULL)
+ {
+ return;
+ }
+ free(record->class);
+ free(record->ref);
+ free(record->obj_uuid);
+ free(record);
+}
+
+
+bool
+xen_event_register(xen_session *session, struct xen_string_set *classes)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string_set,
+ .u.set_val = (arbitrary_set *)classes }
+ };
+
+ xen_call_(session, "event.register", param_values, 1, NULL, NULL);
+ return session->ok;
+}
+
+
+bool
+xen_event_unregister(xen_session *session, struct xen_string_set *classes)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string_set,
+ .u.set_val = (arbitrary_set *)classes }
+ };
+
+ xen_call_(session, "event.unregister", param_values, 1, NULL, NULL);
+ return session->ok;
+}
+
+
+bool
+xen_event_next(xen_session *session, struct xen_event_record_set **result)
+{
+
+ abstract_type result_type = xen_event_record_set_abstract_type_;
+
+ *result = NULL;
+ xen_call_(session, "event.next", NULL, 0, &result_type, result);
+ return session->ok;
+}
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/libxen/src/xen_event_operation.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/src/xen_event_operation.c Fri Mar 30 17:18:42 2007 -0600
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2006-2007, XenSource Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <string.h>
+
+#include "xen_internal.h"
+#include "xen_event_operation.h"
+#include "xen_event_operation_internal.h"
+
+
+/*
+ * Maintain this in the same order as the enum declaration!
+ */
+static const char *lookup_table[] =
+{
+ "add",
+ "del",
+ "mod"
+};
+
+
+extern xen_event_operation_set *
+xen_event_operation_set_alloc(size_t size)
+{
+ return calloc(1, sizeof(xen_event_operation_set) +
+ size * sizeof(enum xen_event_operation));
+}
+
+
+extern void
+xen_event_operation_set_free(xen_event_operation_set *set)
+{
+ free(set);
+}
+
+
+const char *
+xen_event_operation_to_string(enum xen_event_operation val)
+{
+ return lookup_table[val];
+}
+
+
+extern enum xen_event_operation
+xen_event_operation_from_string(xen_session *session, const char *str)
+{
+ return ENUM_LOOKUP(session, str, lookup_table);
+}
+
+
+const abstract_type xen_event_operation_abstract_type_ =
+ {
+ .typename = ENUM,
+ .enum_marshaller =
+ (const char *(*)(int))&xen_event_operation_to_string,
+ .enum_demarshaller =
+ (int (*)(xen_session *, const char
*))&xen_event_operation_from_string
+ };
+
+
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/libxen/src/xen_network.c
--- a/tools/libxen/src/xen_network.c Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/libxen/src/xen_network.c Fri Mar 30 17:18:42 2007 -0600
@@ -24,6 +24,7 @@
#include "xen_internal.h"
#include "xen_network.h"
#include "xen_pif.h"
+#include "xen_string_string_map.h"
#include "xen_vif.h"
@@ -52,7 +53,10 @@ static const struct_member xen_network_r
.offset = offsetof(xen_network_record, vifs) },
{ .key = "PIFs",
.type = &abstract_type_ref_set,
- .offset = offsetof(xen_network_record, pifs) }
+ .offset = offsetof(xen_network_record, pifs) },
+ { .key = "other_config",
+ .type = &abstract_type_string_string_map,
+ .offset = offsetof(xen_network_record, other_config) }
};
const abstract_type xen_network_record_abstract_type_ =
@@ -78,6 +82,7 @@ xen_network_record_free(xen_network_reco
free(record->name_description);
xen_vif_record_opt_set_free(record->vifs);
xen_pif_record_opt_set_free(record->pifs);
+ xen_string_string_map_free(record->other_config);
free(record);
}
@@ -239,6 +244,23 @@ xen_network_get_pifs(xen_session *sessio
bool
+xen_network_get_other_config(xen_session *session, xen_string_string_map
**result, xen_network network)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = network }
+ };
+
+ abstract_type result_type = abstract_type_string_string_map;
+
+ *result = NULL;
+ XEN_CALL_("network.get_other_config");
+ return session->ok;
+}
+
+
+bool
xen_network_set_name_label(xen_session *session, xen_network network, char
*label)
{
abstract_value param_values[] =
@@ -271,6 +293,56 @@ xen_network_set_name_description(xen_ses
bool
+xen_network_set_other_config(xen_session *session, xen_network network,
xen_string_string_map *other_config)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = network },
+ { .type = &abstract_type_string_string_map,
+ .u.set_val = (arbitrary_set *)other_config }
+ };
+
+ xen_call_(session, "network.set_other_config", param_values, 2, NULL,
NULL);
+ return session->ok;
+}
+
+
+bool
+xen_network_add_to_other_config(xen_session *session, xen_network network,
char *key, char *value)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = network },
+ { .type = &abstract_type_string,
+ .u.string_val = key },
+ { .type = &abstract_type_string,
+ .u.string_val = value }
+ };
+
+ xen_call_(session, "network.add_to_other_config", param_values, 3, NULL,
NULL);
+ return session->ok;
+}
+
+
+bool
+xen_network_remove_from_other_config(xen_session *session, xen_network
network, char *key)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = network },
+ { .type = &abstract_type_string,
+ .u.string_val = key }
+ };
+
+ xen_call_(session, "network.remove_from_other_config", param_values, 2,
NULL, NULL);
+ return session->ok;
+}
+
+
+bool
xen_network_get_all(xen_session *session, struct xen_network_set **result)
{
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/libxen/test/test_event_handling.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/test/test_event_handling.c Fri Mar 30 17:18:42 2007 -0600
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2006-2007 XenSource, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define _GNU_SOURCE
+#include <assert.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <libxml/parser.h>
+#include <curl/curl.h>
+
+#include "xen_event.h"
+
+//#define PRINT_XML
+
+static void usage()
+{
+ fprintf(stderr,
+"Usage:\n"
+"\n"
+" test_event_handling <server> <username> <password>\n"
+"\n"
+"where\n"
+" <server> is the server's host and port, e.g. localhost:9363;\n"
+" <username> is the username to use at the server; and\n"
+" <password> is the password.\n");
+
+ exit(EXIT_FAILURE);
+}
+
+
+static char *url;
+
+
+typedef struct
+{
+ xen_result_func func;
+ void *handle;
+} xen_comms;
+
+
+static size_t
+write_func(void *ptr, size_t size, size_t nmemb, xen_comms *comms)
+{
+ size_t n = size * nmemb;
+#ifdef PRINT_XML
+ printf("\n\n---Result from server -----------------------\n");
+ printf("%s\n",((char*) ptr));
+ fflush(stdout);
+#endif
+ return comms->func(ptr, n, comms->handle) ? n : 0;
+}
+
+
+static int
+call_func(const void *data, size_t len, void *user_handle,
+ void *result_handle, xen_result_func result_func)
+{
+ (void)user_handle;
+
+#ifdef PRINT_XML
+ printf("\n\n---Data to server: -----------------------\n");
+ printf("%s\n",((char*) data));
+ fflush(stdout);
+#endif
+
+ CURL *curl = curl_easy_init();
+ if (!curl) {
+ return -1;
+ }
+
+ xen_comms comms = {
+ .func = result_func,
+ .handle = result_handle
+ };
+
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+ curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
+ curl_easy_setopt(curl, CURLOPT_MUTE, 1);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_func);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &comms);
+ curl_easy_setopt(curl, CURLOPT_POST, 1);
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len);
+
+ CURLcode result = curl_easy_perform(curl);
+
+ curl_easy_cleanup(curl);
+
+ return result;
+}
+
+
+static void print_error(xen_session *session)
+{
+ fprintf(stderr, "Error: %d", session->error_description_count);
+ for (int i = 0; i < session->error_description_count; i++)
+ {
+ fprintf(stderr, "%s ", session->error_description[i]);
+ }
+ fprintf(stderr, "\n");
+}
+
+
+/**
+ * Workaround for whinging GCCs, as suggested by strftime(3).
+ */
+static size_t my_strftime(char *s, size_t max, const char *fmt,
+ const struct tm *tm)
+{
+ return strftime(s, max, fmt, tm);
+}
+
+
+int main(int argc, char **argv)
+{
+ if (argc != 4)
+ {
+ usage();
+ }
+
+ url = argv[1];
+ char *username = argv[2];
+ char *password = argv[3];
+
+ xmlInitParser();
+ xen_init();
+ curl_global_init(CURL_GLOBAL_ALL);
+
+#define CLEANUP \
+ do { \
+ xen_session_logout(session); \
+ curl_global_cleanup(); \
+ xen_fini(); \
+ xmlCleanupParser(); \
+ } while(0) \
+
+
+ xen_session *session =
+ xen_session_login_with_password(call_func, NULL, username, password);
+
+ struct xen_string_set *classes = xen_string_set_alloc(0);
+ xen_event_register(session, classes);
+ xen_string_set_free(classes);
+
+ if (!session->ok)
+ {
+ print_error(session);
+ CLEANUP;
+ return 1;
+ }
+
+ while (true)
+ {
+ struct xen_event_record_set *events;
+ if (!xen_event_next(session, &events))
+ {
+ print_error(session);
+ CLEANUP;
+ return 1;
+ }
+
+ for (size_t i = 0; i < events->size; i++)
+ {
+ xen_event_record *ev = events->contents[i];
+ char time[256];
+ struct tm *tm = localtime(&ev->timestamp);
+ my_strftime(time, 256, "%c, local time", tm);
+ printf("Event received: ID = %"PRId64", %s.\n", ev->id, time);
+ switch (ev->operation)
+ {
+ case XEN_EVENT_OPERATION_ADD:
+ printf("%s created with UUID %s.\n", ev->class, ev->obj_uuid);
+ break;
+
+ case XEN_EVENT_OPERATION_DEL:
+ printf("%s with UUID %s deleted.\n", ev->class, ev->obj_uuid);
+ break;
+
+ case XEN_EVENT_OPERATION_MOD:
+ printf("%s with UUID %s modified.\n", ev->class, ev->obj_uuid);
+ break;
+ default:
+ assert(false);
+ }
+ }
+
+ xen_event_record_set_free(events);
+ }
+
+ CLEANUP;
+
+ return 0;
+}
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/pygrub/src/pygrub
--- a/tools/pygrub/src/pygrub Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/pygrub/src/pygrub Fri Mar 30 17:18:42 2007 -0600
@@ -125,16 +125,13 @@ class GrubLineEditor(curses.textpad.Text
is that we can handle lines longer than the window."""
self.win.clear()
- if self.pos > 70:
- if self.pos > 130:
- off = 120
- else:
- off = 55
- l = [ "<" ] + self.line[off:]
- p = self.pos - off
- else:
- l = self.line[:70]
- p = self.pos
+ p = self.pos
+ off = 0
+ while p > 70:
+ p -= 55
+ off += 55
+
+ l = self.line[off:off+70]
self.win.addstr(0, 0, string.join(l, ("")))
if self.pos > 70:
self.win.addch(0, 0, curses.ACS_LARROW)
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/lowlevel/xc/xc.c Fri Mar 30 17:18:42 2007 -0600
@@ -467,6 +467,26 @@ static PyObject *pyxc_linux_build(XcObje
return pyxc_error_to_exception();
}
+static PyObject *pyxc_get_hvm_param(XcObject *self,
+ PyObject *args,
+ PyObject *kwds)
+{
+ uint32_t dom;
+ int param;
+ unsigned long value;
+
+ static char *kwd_list[] = { "domid", "param", NULL };
+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
+ &dom, ¶m) )
+ return NULL;
+
+ if ( xc_get_hvm_param(self->xc_handle, dom, param, &value) != 0 )
+ return pyxc_error_to_exception();
+
+ return Py_BuildValue("i", value);
+
+}
+
static PyObject *pyxc_hvm_build(XcObject *self,
PyObject *args,
PyObject *kwds)
@@ -1224,6 +1244,14 @@ static PyMethodDef pyxc_methods[] = {
" image [str]: Name of HVM loader image file.\n"
" vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
"Returns: [int] 0 on success; -1 on error.\n" },
+
+ { "hvm_get_param",
+ (PyCFunction)pyxc_get_hvm_param,
+ METH_VARARGS | METH_KEYWORDS, "\n"
+ "get a parameter of HVM guest OS.\n"
+ " dom [int]: Identifier of domain to build into.\n"
+ " param [int]: No. of HVM param.\n"
+ "Returns: [int] value of the param.\n" },
{ "sched_id_get",
(PyCFunction)pyxc_sched_id_get,
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/util/xmlrpcclient.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/util/xmlrpcclient.py Fri Mar 30 17:18:42 2007 -0600
@@ -0,0 +1,123 @@
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#============================================================================
+# Copyright (C) 2006 Anthony Liguori <aliguori@xxxxxxxxxx>
+# Copyright (C) 2007 XenSource Inc.
+#============================================================================
+
+
+from httplib import FakeSocket, HTTPConnection, HTTP
+import socket
+import string
+import xmlrpclib
+from types import StringTypes
+
+
+try:
+ import SSHTransport
+ ssh_enabled = True
+except ImportError:
+ # SSHTransport is disabled on Python <2.4, because it uses the subprocess
+ # package.
+ ssh_enabled = False
+
+
+# A new ServerProxy that also supports httpu urls. An http URL comes in the
+# form:
+#
+# httpu:///absolute/path/to/socket.sock
+#
+# It assumes that the RPC handler is /RPC2. This probably needs to be improved
+
+class HTTPUnixConnection(HTTPConnection):
+ def connect(self):
+ self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ self.sock.connect(self.host)
+
+class HTTPUnix(HTTP):
+ _connection_class = HTTPUnixConnection
+
+class UnixTransport(xmlrpclib.Transport):
+ def request(self, host, handler, request_body, verbose=0):
+ self.__handler = handler
+ return xmlrpclib.Transport.request(self, host, '/RPC2',
+ request_body, verbose)
+ def make_connection(self, host):
+ return HTTPUnix(self.__handler)
+
+
+# We need our own transport for HTTPS, because xmlrpclib.SafeTransport is
+# broken -- it does not handle ERROR_ZERO_RETURN properly.
+class HTTPSTransport(xmlrpclib.SafeTransport):
+ def _parse_response(self, file, sock):
+ p, u = self.getparser()
+ while 1:
+ try:
+ if sock:
+ response = sock.recv(1024)
+ else:
+ response = file.read(1024)
+ except socket.sslerror, exn:
+ if exn[0] == socket.SSL_ERROR_ZERO_RETURN:
+ break
+ raise
+
+ if not response:
+ break
+ if self.verbose:
+ print 'body:', repr(response)
+ p.feed(response)
+
+ file.close()
+ p.close()
+ return u.close()
+
+
+# See xmlrpclib2.TCPXMLRPCServer._marshalled_dispatch.
+def conv_string(x):
+ if isinstance(x, StringTypes):
+ s = string.replace(x, "'", r"\047")
+ exec "s = '" + s + "'"
+ return s
+ else:
+ return x
+
+
+class ServerProxy(xmlrpclib.ServerProxy):
+ def __init__(self, uri, transport=None, encoding=None, verbose=0,
+ allow_none=1):
+ if transport == None:
+ (protocol, rest) = uri.split(':', 1)
+ if protocol == 'httpu':
+ uri = 'http:' + rest
+ transport = UnixTransport()
+ elif protocol == 'https':
+ transport = HTTPSTransport()
+ elif protocol == 'ssh':
+ global ssh_enabled
+ if ssh_enabled:
+ (transport, uri) = SSHTransport.getHTTPURI(uri)
+ else:
+ raise ValueError(
+ "SSH transport not supported on Python <2.4.")
+ xmlrpclib.ServerProxy.__init__(self, uri, transport, encoding,
+ verbose, allow_none)
+
+ def __request(self, methodname, params):
+ response = xmlrpclib.ServerProxy.__request(self, methodname, params)
+
+ if isinstance(response, tuple):
+ return tuple([conv_string(x) for x in response])
+ else:
+ return conv_string(response)
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/util/xmlrpclib2.py
--- a/tools/python/xen/util/xmlrpclib2.py Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/util/xmlrpclib2.py Fri Mar 30 17:18:42 2007 -0600
@@ -21,12 +21,10 @@ An enhanced XML-RPC client/server interf
"""
import re
-import string
import fcntl
from types import *
-from httplib import HTTPConnection, HTTP
from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
import SocketServer
import xmlrpclib, socket, os, stat
@@ -35,14 +33,6 @@ import mkdir
from xen.web import connection
from xen.xend.XendLogging import log
-
-try:
- import SSHTransport
- ssh_enabled = True
-except ImportError:
- # SSHTransport is disabled on Python <2.4, because it uses the subprocess
- # package.
- ssh_enabled = False
#
# Convert all integers to strings as described in the Xen API
@@ -64,13 +54,6 @@ def stringify(value):
return value
-# A new ServerProxy that also supports httpu urls. An http URL comes in the
-# form:
-#
-# httpu:///absolute/path/to/socket.sock
-#
-# It assumes that the RPC handler is /RPC2. This probably needs to be improved
-
# We're forced to subclass the RequestHandler class so that we can work around
# some bugs in Keep-Alive handling and also enabled it by default
class XMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
@@ -105,60 +88,6 @@ class XMLRPCRequestHandler(SimpleXMLRPCR
self.wfile.flush()
if self.close_connection == 1:
self.connection.shutdown(1)
-
-class HTTPUnixConnection(HTTPConnection):
- def connect(self):
- self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- self.sock.connect(self.host)
-
-class HTTPUnix(HTTP):
- _connection_class = HTTPUnixConnection
-
-class UnixTransport(xmlrpclib.Transport):
- def request(self, host, handler, request_body, verbose=0):
- self.__handler = handler
- return xmlrpclib.Transport.request(self, host, '/RPC2',
- request_body, verbose)
- def make_connection(self, host):
- return HTTPUnix(self.__handler)
-
-
-# See _marshalled_dispatch below.
-def conv_string(x):
- if isinstance(x, StringTypes):
- s = string.replace(x, "'", r"\047")
- exec "s = '" + s + "'"
- return s
- else:
- return x
-
-
-class ServerProxy(xmlrpclib.ServerProxy):
- def __init__(self, uri, transport=None, encoding=None, verbose=0,
- allow_none=1):
- if transport == None:
- (protocol, rest) = uri.split(':', 1)
- if protocol == 'httpu':
- uri = 'http:' + rest
- transport = UnixTransport()
- elif protocol == 'ssh':
- global ssh_enabled
- if ssh_enabled:
- (transport, uri) = SSHTransport.getHTTPURI(uri)
- else:
- raise ValueError(
- "SSH transport not supported on Python <2.4.")
- xmlrpclib.ServerProxy.__init__(self, uri, transport, encoding,
- verbose, allow_none)
-
- def __request(self, methodname, params):
- response = xmlrpclib.ServerProxy.__request(self, methodname, params)
-
- if isinstance(response, tuple):
- return tuple([conv_string(x) for x in response])
- else:
- return conv_string(response)
-
# This is a base XML-RPC server for TCP. It sets allow_reuse_address to
# true, and has an improved marshaller that logs and serializes exceptions.
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendAPI.py Fri Mar 30 17:18:42 2007 -0600
@@ -17,6 +17,8 @@
import inspect
import os
+import Queue
+import sets
import string
import sys
import traceback
@@ -32,7 +34,9 @@ from xen.xend.XendError import *
from xen.xend.XendError import *
from xen.xend.XendClient import ERROR_INVALID_DOMAIN
from xen.xend.XendLogging import log
+from xen.xend.XendNetwork import XendNetwork
from xen.xend.XendTask import XendTask
+from xen.xend.XendPIFMetrics import XendPIFMetrics
from xen.xend.XendVMMetrics import XendVMMetrics
from xen.xend.XendAPIConstants import *
@@ -82,6 +86,91 @@ def xen_api_todo():
def now():
return xmlrpclib.DateTime(time.strftime("%Y%m%dT%H:%M:%S", time.gmtime()))
+
+
+# ---------------------------------------------------
+# Event dispatch
+# ---------------------------------------------------
+
+EVENT_QUEUE_LENGTH = 50
+event_registrations = {}
+
+def event_register(session, reg_classes):
+ if session not in event_registrations:
+ event_registrations[session] = {
+ 'classes' : sets.Set(),
+ 'queue' : Queue.Queue(EVENT_QUEUE_LENGTH),
+ 'next-id' : 1
+ }
+ if not reg_classes:
+ reg_classes = classes
+ event_registrations[session]['classes'].union_update(reg_classes)
+
+
+def event_unregister(session, unreg_classes):
+ if session not in event_registrations:
+ return
+
+ if unreg_classes:
+ event_registrations[session]['classes'].intersection_update(
+ unreg_classes)
+ if len(event_registrations[session]['classes']) == 0:
+ del event_registrations[session]
+ else:
+ del event_registrations[session]
+
+
+def event_next(session):
+ if session not in event_registrations:
+ return xen_api_error(['SESSION_NOT_REGISTERED', session])
+ queue = event_registrations[session]['queue']
+ events = [queue.get()]
+ try:
+ while True:
+ events.append(queue.get(False))
+ except Queue.Empty:
+ pass
+
+ return xen_api_success(events)
+
+
+def _ctor_event_dispatch(xenapi, ctor, api_cls, session, args):
+ result = ctor(xenapi, session, *args)
+ if result['Status'] == 'Success':
+ ref = result['Value']
+ _event_dispatch('add', api_cls, ref, '')
+ return result
+
+
+def _dtor_event_dispatch(xenapi, dtor, api_cls, session, ref, args):
+ result = dtor(xenapi, session, ref, *args)
+ if result['Status'] == 'Success':
+ _event_dispatch('del', api_cls, ref, '')
+ return result
+
+
+def _setter_event_dispatch(xenapi, setter, api_cls, attr_name, session, ref,
+ args):
+ result = setter(xenapi, session, ref, *args)
+ if result['Status'] == 'Success':
+ _event_dispatch('mod', api_cls, ref, attr_name)
+ return result
+
+
+def _event_dispatch(operation, api_cls, ref, attr_name):
+ event = {
+ 'timestamp' : now(),
+ 'class' : api_cls,
+ 'operation' : operation,
+ 'ref' : ref,
+ 'obj_uuid' : ref,
+ 'field' : attr_name,
+ }
+ for reg in event_registrations.values():
+ if api_cls in reg['classes']:
+ event['id'] = reg['next-id']
+ reg['next-id'] += 1
+ reg['queue'].put(event)
# ---------------------------------------------------
@@ -373,6 +462,36 @@ def do_vm_func(fn_name, vm_ref, *args, *
exn.actual])
+classes = {
+ 'session' : None,
+ 'event' : None,
+ 'host' : valid_host,
+ 'host_cpu' : valid_host_cpu,
+ 'host_metrics' : valid_host_metrics,
+ 'network' : valid_network,
+ 'VM' : valid_vm,
+ 'VM_metrics' : valid_vm_metrics,
+ 'VBD' : valid_vbd,
+ 'VBD_metrics' : valid_vbd_metrics,
+ 'VIF' : valid_vif,
+ 'VIF_metrics' : valid_vif_metrics,
+ 'VDI' : valid_vdi,
+ 'VTPM' : valid_vtpm,
+ 'console' : valid_console,
+ 'SR' : valid_sr,
+ 'PIF' : valid_pif,
+ 'PIF_metrics' : valid_pif_metrics,
+ 'task' : valid_task,
+ 'debug' : valid_debug,
+}
+
+autoplug_classes = {
+ 'network' : XendNetwork,
+ 'VM_metrics' : XendVMMetrics,
+ 'PIF_metrics' : XendPIFMetrics,
+}
+
+
class XendAPI(object):
"""Implementation of the Xen-API in Xend. Expects to be
used via XMLRPCServer.
@@ -414,27 +533,7 @@ class XendAPI(object):
server.
"""
global_validators = [session_required, catch_typeerror]
- classes = {
- 'session' : None,
- 'host' : valid_host,
- 'host_cpu' : valid_host_cpu,
- 'host_metrics' : valid_host_metrics,
- 'network' : valid_network,
- 'VM' : valid_vm,
- 'VM_metrics' : valid_vm_metrics,
- 'VBD' : valid_vbd,
- 'VBD_metrics' : valid_vbd_metrics,
- 'VIF' : valid_vif,
- 'VIF_metrics' : valid_vif_metrics,
- 'VDI' : valid_vdi,
- 'VTPM' : valid_vtpm,
- 'console' : valid_console,
- 'SR' : valid_sr,
- 'PIF' : valid_pif,
- 'PIF_metrics' : valid_pif_metrics,
- 'task' : valid_task,
- 'debug' : valid_debug,
- }
+
# Cheat methods
# -------------
@@ -457,6 +556,77 @@ class XendAPI(object):
setattr(cls, get_by_uuid, _get_by_uuid)
setattr(cls, get_uuid, _get_uuid)
+
+ # Autoplugging classes
+ # --------------------
+ # These have all of their methods grabbed out from the implementation
+ # class, and wrapped up to be compatible with the Xen-API.
+
+ for api_cls, impl_cls in autoplug_classes.items():
+ def doit(n):
+ getter = getattr(cls, '_%s_get' % api_cls)
+ dot_n = '%s.%s' % (api_cls, n)
+ full_n = '%s_%s' % (api_cls, n)
+ if not hasattr(cls, full_n):
+ f = getattr(impl_cls, n)
+ argcounts[dot_n] = f.func_code.co_argcount + 1
+ setattr(cls, full_n,
+ lambda s, session, ref, *args: \
+ xen_api_success( \
+ f(getter(s, session, ref), *args)))
+
+ ro_attrs = getattr(cls, '%s_attr_ro' % api_cls, [])
+ rw_attrs = getattr(cls, '%s_attr_rw' % api_cls, [])
+ methods = getattr(cls, '%s_methods' % api_cls, [])
+ funcs = getattr(cls, '%s_funcs' % api_cls, [])
+
+ for attr_name in ro_attrs + rw_attrs:
+ doit('get_%s' % attr_name)
+ for attr_name in rw_attrs + cls.Base_attr_rw:
+ doit('set_%s' % attr_name)
+ for method_name, return_type in methods + cls.Base_methods:
+ doit('%s' % method_name)
+ for func_name, return_type in funcs + cls.Base_funcs:
+ doit('%s' % func_name)
+
+
+ def wrap_method(name, new_f):
+ try:
+ f = getattr(cls, name)
+ wrapped_f = (lambda *args: new_f(f, *args))
+ wrapped_f.api = f.api
+ wrapped_f.async = f.async
+ setattr(cls, name, wrapped_f)
+ except AttributeError:
+ # Logged below (API call: %s not found)
+ pass
+
+
+ def setter_event_wrapper(api_cls, attr_name):
+ setter_name = '%s_set_%s' % (api_cls, attr_name)
+ wrap_method(
+ setter_name,
+ lambda setter, s, session, ref, *args:
+ _setter_event_dispatch(s, setter, api_cls, attr_name,
+ session, ref, args))
+
+
+ def ctor_event_wrapper(api_cls):
+ ctor_name = '%s_create' % api_cls
+ wrap_method(
+ ctor_name,
+ lambda ctor, s, session, *args:
+ _ctor_event_dispatch(s, ctor, api_cls, session, args))
+
+
+ def dtor_event_wrapper(api_cls):
+ dtor_name = '%s_destroy' % api_cls
+ wrap_method(
+ dtor_name,
+ lambda dtor, s, session, ref, *args:
+ _dtor_event_dispatch(s, dtor, api_cls, session, ref, args))
+
+
# Wrapping validators around XMLRPC calls
# ---------------------------------------
@@ -466,7 +636,8 @@ class XendAPI(object):
n_ = n.replace('.', '_')
try:
f = getattr(cls, n_)
- argcounts[n] = f.func_code.co_argcount - 1
+ if n not in argcounts:
+ argcounts[n] = f.func_code.co_argcount - 1
validators = takes_instance and validator and \
[validator] or []
@@ -498,6 +669,7 @@ class XendAPI(object):
for attr_name in rw_attrs + cls.Base_attr_rw:
doit('%s.set_%s' % (api_cls, attr_name), True,
async_support = False)
+ setter_event_wrapper(api_cls, attr_name)
# wrap validators around methods
for method_name, return_type in methods + cls.Base_methods:
@@ -509,6 +681,10 @@ class XendAPI(object):
doit('%s.%s' % (api_cls, func_name), False, async_support =
True,
return_type = return_type)
+ ctor_event_wrapper(api_cls)
+ dtor_event_wrapper(api_cls)
+
+
_decorate = classmethod(_decorate)
def __init__(self, auth):
@@ -516,7 +692,7 @@ class XendAPI(object):
Base_attr_ro = ['uuid']
Base_attr_rw = []
- Base_methods = [('destroy', None), ('get_record', 'Struct')]
+ Base_methods = [('get_record', 'Struct')]
Base_funcs = [('get_all', 'Set'), ('get_by_uuid', None)]
# Xen API: Class Session
@@ -916,59 +1092,40 @@ class XendAPI(object):
network_attr_ro = ['VIFs', 'PIFs']
network_attr_rw = ['name_label',
- 'name_description']
-
- network_funcs = [('create', 'network')]
-
- def network_create(self, _, name_label, name_description):
- return xen_api_success(
- XendNode.instance().network_create(name_label, name_description))
+ 'name_description',
+ 'other_config']
+ network_methods = [('add_to_other_config', None),
+ ('remove_from_other_config', None),
+ ('destroy', None)]
+ network_funcs = [('create', None)]
+
+ def _network_get(self, _, ref):
+ return XendNode.instance().get_network(ref)
+
+ def network_get_all(self, _):
+ return xen_api_success(XendNode.instance().get_network_refs())
+
+ def network_create(self, _, record):
+ return xen_api_success(XendNode.instance().network_create(record))
def network_destroy(self, _, ref):
return xen_api_success(XendNode.instance().network_destroy(ref))
- def _get_network(self, ref):
- return XendNode.instance().get_network(ref)
-
- def network_get_all(self, _):
- return xen_api_success(XendNode.instance().get_network_refs())
-
- def network_get_record(self, _, ref):
- return xen_api_success(
- XendNode.instance().get_network(ref).get_record())
-
- def network_get_name_label(self, _, ref):
- return xen_api_success(self._get_network(ref).name_label)
-
- def network_get_name_description(self, _, ref):
- return xen_api_success(self._get_network(ref).name_description)
-
- def network_get_VIFs(self, _, ref):
- return xen_api_success(self._get_network(ref).get_VIF_UUIDs())
-
- def network_get_PIFs(self, session, ref):
- return xen_api_success(self._get_network(ref).get_PIF_UUIDs())
-
- def network_set_name_label(self, _, ref, val):
- return xen_api_success(self._get_network(ref).set_name_label(val))
-
- def network_set_name_description(self, _, ref, val):
- return
xen_api_success(self._get_network(ref).set_name_description(val))
# Xen API: Class PIF
# ----------------------------------------------------------------
- PIF_attr_ro = ['metrics']
+ PIF_attr_ro = ['network',
+ 'host',
+ 'metrics']
PIF_attr_rw = ['device',
- 'network',
- 'host',
'MAC',
'MTU',
'VLAN']
PIF_attr_inst = PIF_attr_rw
- PIF_methods = [('create_VLAN', 'int')]
+ PIF_methods = [('create_VLAN', 'int'), ('destroy', None)]
def _get_PIF(self, ref):
return XendNode.instance().pifs[ref]
@@ -1044,25 +1201,13 @@ class XendAPI(object):
'io_write_kbs',
'last_updated']
PIF_metrics_attr_rw = []
- PIF_methods = []
+ PIF_metrics_methods = []
def PIF_metrics_get_all(self, _):
return xen_api_success(XendNode.instance().pif_metrics.keys())
- def _PIF_metrics_get(self, ref):
+ def _PIF_metrics_get(self, _, ref):
return XendNode.instance().pif_metrics[ref]
-
- def PIF_metrics_get_record(self, _, ref):
- return xen_api_success(self._PIF_metrics_get(ref).get_record())
-
- def PIF_metrics_get_io_read_kbs(self, _, ref):
- return xen_api_success(self._PIF_metrics_get(ref).get_io_read_kbs())
-
- def PIF_metrics_get_io_write_kbs(self, _, ref):
- return xen_api_success(self._PIF_metrics_get(ref).get_io_write_kbs())
-
- def PIF_metrics_get_last_updated(self, _1, _2):
- return xen_api_success(now())
# Xen API: Class VM
@@ -1131,7 +1276,8 @@ class XendAPI(object):
('save', None),
('set_memory_dynamic_max_live', None),
('set_memory_dynamic_min_live', None),
- ('send_trigger', None)]
+ ('send_trigger', None),
+ ('destroy', None)]
VM_funcs = [('create', 'VM'),
('restore', None),
@@ -1390,7 +1536,8 @@ class XendAPI(object):
if key.startswith("cpumap"):
vcpu = int(key[6:])
try:
- xendom.domain_pincpu(xeninfo.getDomid(), vcpu, value)
+ cpus = map(int, value.split(","))
+ xendom.domain_pincpu(xeninfo.getDomid(), vcpu, cpus)
except Exception, ex:
log.exception(ex)
@@ -1633,14 +1780,15 @@ class XendAPI(object):
def VM_send_sysrq(self, _, vm_ref, req):
xeninfo = XendDomain.instance().get_vm_by_uuid(vm_ref)
- if xeninfo.state != XEN_API_VM_POWER_STATE_RUNNING:
+ if xeninfo.state == XEN_API_VM_POWER_STATE_RUNNING \
+ or xeninfo.state == XEN_API_VM_POWER_STATE_PAUSED:
+ xeninfo.send_sysrq(req)
+ return xen_api_success_void()
+ else:
return xen_api_error(
['VM_BAD_POWER_STATE', vm_ref,
XendDomain.POWER_STATE_NAMES[XEN_API_VM_POWER_STATE_RUNNING],
XendDomain.POWER_STATE_NAMES[xeninfo.state]])
- xeninfo.send_sysrq(req)
- return xen_api_success_void()
-
def VM_send_trigger(self, _, vm_ref, trigger, vcpu):
xendom = XendDomain.instance()
@@ -1675,58 +1823,28 @@ class XendAPI(object):
VM_metrics_attr_rw = []
VM_metrics_methods = []
- def _VM_metrics_get(self, ref):
+ def _VM_metrics_get(self, _, ref):
return XendVMMetrics.get_by_uuid(ref)
def VM_metrics_get_all(self, _):
return xen_api_success(XendVMMetrics.get_all())
- def VM_metrics_get_record(self, _, ref):
- return xen_api_success(self._VM_metrics_get(ref).get_record())
-
- def VM_metrics_get_memory_actual(self, _, ref):
- return xen_api_success(self._VM_metrics_get(ref).get_memory_actual())
-
- def VM_metrics_get_VCPUs_number(self, _, ref):
- return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_number())
-
- def VM_metrics_get_VCPUs_utilisation(self, _, ref):
- return
xen_api_success(self._VM_metrics_get(ref).get_VCPUs_utilisation())
-
- def VM_metrics_get_VCPUs_CPU(self, _, ref):
- return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_CPU())
-
- def VM_metrics_get_VCPUs_flags(self, _, ref):
- return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_flags())
-
- def VM_metrics_get_VCPUs_params(self, _, ref):
- return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_params())
-
- def VM_metrics_get_start_time(self, _, ref):
- return xen_api_success(self._VM_metrics_get(ref).get_start_time())
-
- def VM_metrics_get_state(self, _, ref):
- return xen_api_success(self._VM_metrics_get(ref).get_state())
-
- def VM_metrics_get_last_updated(self, _1, _2):
- return xen_api_success(now())
-
# Xen API: Class VBD
# ----------------------------------------------------------------
- VBD_attr_ro = ['metrics',
+ VBD_attr_ro = ['VM',
+ 'VDI',
+ 'metrics',
'runtime_properties']
- VBD_attr_rw = ['VM',
- 'VDI',
- 'device',
+ VBD_attr_rw = ['device',
'bootable',
'mode',
'type']
VBD_attr_inst = VBD_attr_rw
- VBD_methods = [('media_change', None)]
+ VBD_methods = [('media_change', None), ('destroy', None)]
VBD_funcs = [('create', 'VBD')]
# object methods
@@ -1868,7 +1986,10 @@ class XendAPI(object):
'io_write_kbs',
'last_updated']
VBD_metrics_attr_rw = []
- VBD_methods = []
+ VBD_metrics_methods = []
+
+ def VBD_metrics_get_all(self, session):
+ return self.VBD_get_all(session)
def VBD_metrics_get_record(self, _, ref):
vm = XendDomain.instance().get_vm_with_dev_uuid('vbd', ref)
@@ -1893,16 +2014,17 @@ class XendAPI(object):
# Xen API: Class VIF
# ----------------------------------------------------------------
- VIF_attr_ro = ['metrics',
+ VIF_attr_ro = ['network',
+ 'VM',
+ 'metrics',
'runtime_properties']
VIF_attr_rw = ['device',
- 'network',
- 'VM',
'MAC',
'MTU']
VIF_attr_inst = VIF_attr_rw
+ VIF_methods = [('destroy', None)]
VIF_funcs = [('create', 'VIF')]
@@ -1960,10 +2082,10 @@ class XendAPI(object):
return xen_api_success(vif_ref)
def VIF_get_VM(self, session, vif_ref):
- xendom = XendDomain.instance()
- vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
+ xendom = XendDomain.instance()
+ vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
return xen_api_success(vm.get_uuid())
-
+
def VIF_get_MTU(self, session, vif_ref):
return self._VIF_get(vif_ref, 'MTU')
@@ -2008,7 +2130,10 @@ class XendAPI(object):
'io_write_kbs',
'last_updated']
VIF_metrics_attr_rw = []
- VIF_methods = []
+ VIF_metrics_methods = []
+
+ def VIF_metrics_get_all(self, session):
+ return self.VIF_get_all(session)
def VIF_metrics_get_record(self, _, ref):
vm = XendDomain.instance().get_vm_with_dev_uuid('vif', ref)
@@ -2044,7 +2169,7 @@ class XendAPI(object):
'other_config']
VDI_attr_inst = VDI_attr_ro + VDI_attr_rw
- VDI_methods = [('snapshot', 'VDI')]
+ VDI_methods = [('snapshot', 'VDI'), ('destroy', None)]
VDI_funcs = [('create', 'VDI'),
('get_by_name_label', 'Set(VDI)')]
@@ -2161,6 +2286,7 @@ class XendAPI(object):
VTPM_attr_inst = VTPM_attr_rw
+ VTPM_methods = [('destroy', None)]
VTPM_funcs = [('create', 'VTPM')]
# object methods
@@ -2319,7 +2445,7 @@ class XendAPI(object):
'name_label',
'name_description']
- SR_methods = [('clone', 'SR')]
+ SR_methods = [('clone', 'SR'), ('destroy', None)]
SR_funcs = [('get_by_name_label', 'Set(SR)'),
('get_by_uuid', 'SR')]
@@ -2394,6 +2520,26 @@ class XendAPI(object):
XendNode.instance().save()
return xen_api_success_void()
+
+ # Xen API: Class event
+ # ----------------------------------------------------------------
+
+ event_attr_ro = []
+ event_attr_rw = []
+ event_funcs = [('register', None),
+ ('unregister', None),
+ ('next', None)]
+
+ def event_register(self, session, reg_classes):
+ event_register(session, reg_classes)
+ return xen_api_success_void()
+
+ def event_unregister(self, session, unreg_classes):
+ event_unregister(session, reg_classes)
+ return xen_api_success_void()
+
+ def event_next(self, session):
+ return event_next(session)
# Xen API: Class debug
# ----------------------------------------------------------------
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendCheckpoint.py Fri Mar 30 17:18:42 2007 -0600
@@ -192,13 +192,11 @@ def restore(xd, fd, dominfo = None, paus
image_cfg = dominfo.info.get('image', {})
is_hvm = dominfo.info.is_hvm()
if is_hvm:
- hvm = dominfo.info['memory_static_min']
apic = int(dominfo.info['platform'].get('apic', 0))
pae = int(dominfo.info['platform'].get('pae', 0))
- log.info("restore hvm domain %d, mem=%d, apic=%d, pae=%d",
- dominfo.domid, hvm, apic, pae)
+ log.info("restore hvm domain %d, apic=%d, pae=%d",
+ dominfo.domid, apic, pae)
else:
- hvm = 0
apic = 0
pae = 0
@@ -224,7 +222,7 @@ def restore(xd, fd, dominfo = None, paus
cmd = map(str, [xen.util.auxbin.pathTo(XC_RESTORE),
fd, dominfo.getDomid(), max_pfn,
- store_port, console_port, hvm, pae, apic])
+ store_port, console_port, int(is_hvm), pae, apic])
log.debug("[xc_restore]: %s", string.join(cmd))
handler = RestoreInputHandler()
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendClient.py
--- a/tools/python/xen/xend/XendClient.py Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendClient.py Fri Mar 30 17:18:42 2007 -0600
@@ -17,7 +17,7 @@
# Copyright (C) 2006 Anthony Liguori <aliguori@xxxxxxxxxx>
#============================================================================
-from xen.util.xmlrpclib2 import ServerProxy
+from xen.util.xmlrpcclient import ServerProxy
import os
import sys
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendConfig.py Fri Mar 30 17:18:42 2007 -0600
@@ -298,7 +298,7 @@ class XendConfig(dict):
'actions_after_reboot': 'restart',
'actions_after_crash': 'restart',
'actions_after_suspend': '',
- 'is_template': False,
+ 'is_a_template': False,
'is_control_domain': False,
'features': '',
'PV_bootloader': '',
@@ -452,7 +452,10 @@ class XendConfig(dict):
for key, typ in XENAPI_CFG_TYPES.items():
val = sxp.child_value(sxp_cfg, key)
if val is not None:
- cfg[key] = typ(val)
+ try:
+ cfg[key] = typ(val)
+ except (ValueError, TypeError), e:
+ log.warn('Unable to convert type value for key: %s' % key)
# Convert deprecated options to current equivalents.
@@ -727,7 +730,7 @@ class XendConfig(dict):
for key in XENAPI_PLATFORM_CFG:
val = sxp.child_value(image_sxp, key, None)
- if val is not None:
+ if val is not None and val != '':
self['platform'][key] = val
notes = sxp.children(image_sxp, 'notes')
@@ -845,6 +848,8 @@ class XendConfig(dict):
sxpr.append([name, s])
for xenapi, legacy in XENAPI_CFG_TO_LEGACY_CFG.items():
+ if legacy in ('cpus'): # skip this
+ continue
if self.has_key(xenapi) and self[xenapi] not in (None, []):
if type(self[xenapi]) == bool:
# convert booleans to ints before making an sxp item
@@ -858,7 +863,7 @@ class XendConfig(dict):
sxpr.append(["memory", int(self["memory_dynamic_max"])/MiB])
for legacy in LEGACY_UNSUPPORTED_BY_XENAPI_CFG:
- if legacy in ('domid', 'uuid'): # skip these
+ if legacy in ('domid', 'uuid', 'cpus'): # skip these
continue
if self.has_key(legacy) and self[legacy] not in (None, []):
sxpr.append([legacy, self[legacy]])
@@ -1354,7 +1359,7 @@ class XendConfig(dict):
for key in XENAPI_PLATFORM_CFG:
val = sxp.child_value(image_sxp, key, None)
- if val is not None:
+ if val is not None and val != '':
self['platform'][key] = val
notes = sxp.children(image_sxp, 'notes')
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendConstants.py
--- a/tools/python/xen/xend/XendConstants.py Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendConstants.py Fri Mar 30 17:18:42 2007 -0600
@@ -36,6 +36,13 @@ DOMAIN_SHUTDOWN_REASONS = {
}
REVERSE_DOMAIN_SHUTDOWN_REASONS = \
dict([(y, x) for x, y in DOMAIN_SHUTDOWN_REASONS.items()])
+
+HVM_PARAM_CALLBACK_IRQ = 0
+HVM_PARAM_STORE_PFN = 1
+HVM_PARAM_STORE_EVTCHN = 2
+HVM_PARAM_PAE_ENABLED = 4
+HVM_PARAM_IOREQ_PFN = 5
+HVM_PARAM_BUFIOREQ_PFN = 6
restart_modes = [
"restart",
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendDomain.py Fri Mar 30 17:18:42 2007 -0600
@@ -569,6 +569,26 @@ class XendDomain:
finally:
self.domains_lock.release()
+ def autostart_domains(self):
+ """ Autostart managed domains that are marked as such. """
+
+ need_starting = []
+
+ self.domains_lock.acquire()
+ try:
+ for dom_uuid, dom in self.managed_domains.items():
+ if dom and dom.state == DOM_STATE_HALTED:
+ on_xend_start = dom.info.get('on_xend_start', 'ignore')
+ auto_power_on = dom.info.get('auto_power_on', False)
+ should_start = (on_xend_start == 'start') or auto_power_on
+ if should_start:
+ need_starting.append(dom_uuid)
+ finally:
+ self.domains_lock.release()
+
+ for dom_uuid in need_starting:
+ self.domain_start(dom_uuid, False)
+
def cleanup_domains(self):
"""Clean up domains that are marked as autostop.
Should be called when Xend goes down. This is currently
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendDomainInfo.py Fri Mar 30 17:18:42 2007 -0600
@@ -152,8 +152,9 @@ def recreate(info, priv):
try:
vmpath = xstransact.Read(dompath, "vm")
if not vmpath:
- log.warn('/local/domain/%d/vm is missing. recreate is '
- 'confused, trying our best to recover' % domid)
+ if not priv:
+ log.warn('/local/domain/%d/vm is missing. recreate is '
+ 'confused, trying our best to recover' % domid)
needs_reinitialising = True
raise XendError('reinit')
@@ -447,13 +448,13 @@ class XendDomainInfo:
self._removeVm('xend/previous_restart_time')
self.storeDom("control/shutdown", reason)
- ## shutdown hypercall for hvm domain desides xenstore write
+ # HVM domain shuts itself down only if it has PV drivers
if self.info.is_hvm():
- for code in DOMAIN_SHUTDOWN_REASONS.keys():
- if DOMAIN_SHUTDOWN_REASONS[code] == reason:
- break
- xc.domain_shutdown(self.domid, code)
-
+ hvm_pvdrv = xc.hvm_get_param(self.domid, HVM_PARAM_CALLBACK_IRQ)
+ if not hvm_pvdrv:
+ code = REVERSE_DOMAIN_SHUTDOWN_REASONS[reason]
+ log.info("HVM save:remote shutdown dom %d!", self.domid)
+ xc.domain_shutdown(self.domid, code)
def pause(self):
"""Pause domain
@@ -2354,7 +2355,8 @@ class XendDomainInfo:
if not dev_uuid:
raise XendError('Failed to create device')
- if self.state == XEN_API_VM_POWER_STATE_RUNNING:
+ if self.state == XEN_API_VM_POWER_STATE_RUNNING \
+ or self.state == XEN_API_VM_POWER_STATE_PAUSED:
_, config = self.info['devices'][dev_uuid]
dev_control = self.getDeviceController('vif')
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendLogging.py
--- a/tools/python/xen/xend/XendLogging.py Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendLogging.py Fri Mar 30 17:18:42 2007 -0600
@@ -62,6 +62,7 @@ if 'TRACE' not in logging.__dict__:
# Work around a bug in Python's inspect module: findsource is supposed to
# raise IOError if it fails, with other functions in that module coping
# with that, but some people are seeing IndexError raised from there.
+ # This is Python bug 1628987. http://python.org/sf/1628987.
if hasattr(inspect, 'findsource'):
real_findsource = getattr(inspect, 'findsource')
def findsource(*args, **kwargs):
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendMonitor.py
--- a/tools/python/xen/xend/XendMonitor.py Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendMonitor.py Fri Mar 30 17:18:42 2007 -0600
@@ -24,8 +24,8 @@ import re
"""Monitoring thread to keep track of Xend statistics. """
VBD_SYSFS_PATH = '/sys/devices/xen-backend/'
-VBD_WR_PATH = VBD_SYSFS_PATH + '%s/statistics/wr_req'
-VBD_RD_PATH = VBD_SYSFS_PATH + '%s/statistics/rd_req'
+VBD_WR_PATH = VBD_SYSFS_PATH + '%s/statistics/wr_sect'
+VBD_RD_PATH = VBD_SYSFS_PATH + '%s/statistics/rd_sect'
VBD_DOMAIN_RE = r'vbd-(?P<domid>\d+)-(?P<devid>\d+)$'
NET_PROCFS_PATH = '/proc/net/dev'
@@ -51,14 +51,9 @@ VIF_DOMAIN_RE = re.compile(r'vif(?P<domi
PROC_NET_DEV_RE)
PIF_RE = re.compile(r'^\s*(?P<iface>peth\d+):\s*' + PROC_NET_DEV_RE)
-# The VBD transfer figures are in "requests" where we don't
-# really know how many bytes per requests. For now we make
-# up a number roughly could be.
-VBD_ROUGH_BYTES_PER_REQUEST = 1024 * 8 * 4
-
# Interval to poll xc, sysfs and proc
POLL_INTERVAL = 2.0
-
+SECTOR_SIZE = 512
class XendMonitor(threading.Thread):
"""Monitors VCPU, VBD, VIF and PIF statistics for Xen API.
@@ -186,9 +181,8 @@ class XendMonitor(threading.Thread):
usage_at = time.time()
rd_stat = int(open(rd_stat_path).readline().strip())
wr_stat = int(open(wr_stat_path).readline().strip())
- rd_stat *= VBD_ROUGH_BYTES_PER_REQUEST
- wr_stat *= VBD_ROUGH_BYTES_PER_REQUEST
-
+ rd_stat *= SECTOR_SIZE
+ wr_stat *= SECTOR_SIZE
if domid not in stats:
stats[domid] = {}
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendNetwork.py
--- a/tools/python/xen/xend/XendNetwork.py Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendNetwork.py Fri Mar 30 17:18:42 2007 -0600
@@ -28,10 +28,17 @@ IP_ROUTE_RE = r'^default via ([\d\.]+) d
IP_ROUTE_RE = r'^default via ([\d\.]+) dev (\w+)'
class XendNetwork:
- def __init__(self, uuid, name, description):
+ def __init__(self, uuid, record):
self.uuid = uuid
- self.name_label = name
- self.name_description = description
+ self.name_label = record.get('name_label', '')
+ self.name_description = record.get('name_description', '')
+ self.other_config = record.get('other_config', {})
+
+ def get_name_label(self):
+ return self.name_label
+
+ def get_name_description(self):
+ return self.name_description
def set_name_label(self, new_name):
self.name_label = new_name
@@ -41,7 +48,7 @@ class XendNetwork:
self.name_description = new_desc
XendNode.instance().save_networks()
- def get_VIF_UUIDs(self):
+ def get_VIFs(self):
result = []
vms = XendDomain.instance().get_all_vms()
for vm in vms:
@@ -52,17 +59,37 @@ class XendNetwork:
result.append(vif)
return result
- def get_PIF_UUIDs(self):
+ def get_PIFs(self):
return [x.uuid for x in XendNode.instance().pifs.values()
if x.network == self]
- def get_record(self, transient = True):
+ def get_other_config(self):
+ return self.other_config
+
+ def set_other_config(self, value):
+ self.other_config = value
+ XendNode.instance().save_networks()
+
+ def add_to_other_config(self, key, value):
+ self.other_config[key] = value
+ XendNode.instance().save_networks()
+
+ def remove_from_other_config(self, key):
+ if key in self.other_config:
+ del self.other_config[key]
+ XendNode.instance().save_networks()
+
+ def get_record(self):
+ return self.get_record_internal(True)
+
+ def get_record_internal(self, transient):
result = {
'uuid': self.uuid,
'name_label': self.name_label,
'name_description': self.name_description,
+ 'other_config' : self.other_config,
}
if transient:
- result['VIFs'] = self.get_VIF_UUIDs()
- result['PIFs'] = self.get_PIF_UUIDs()
+ result['VIFs'] = self.get_VIFs()
+ result['PIFs'] = self.get_PIFs()
return result
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendNode.py
--- a/tools/python/xen/xend/XendNode.py Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendNode.py Fri Mar 30 17:18:42 2007 -0600
@@ -141,12 +141,16 @@ class XendNode:
saved_networks = self.state_store.load_state('network')
if saved_networks:
for net_uuid, network in saved_networks.items():
- self.network_create(network.get('name_label'),
- network.get('name_description', ''),
- False, net_uuid)
+ self.network_create(network, False, net_uuid)
else:
- self.network_create('net0', '', False)
-
+ bridges = Brctl.get_state().keys()
+ for bridge in bridges:
+ self.network_create({'name_label' : bridge }, False)
+
+ # Get a mapping from interface to bridge
+
+ if_to_br = dict(reduce(lambda ls,(b,ifs):[(i,b) for i in ifs] + ls,
+ Brctl.get_state().items(), []))
# initialise PIFs
saved_pifs = self.state_store.load_state('pif')
if saved_pifs:
@@ -176,8 +180,14 @@ class XendNode:
pif_uuid, pif['network'], exn.pif_uuid)
else:
for name, mtu, mac in linux_get_phy_ifaces():
- network = self.networks.values()[0]
- self._PIF_create(name, mtu, -1, mac, network, False)
+ bridge_name = if_to_br.get(name, None)
+ if bridge_name is not None:
+ networks = [network for
+ network in self.networks.values()
+ if network.get_name_label() == bridge_name]
+ if len(networks) > 0:
+ network = networks[0]
+ self._PIF_create(name, mtu, -1, mac, network, False)
# initialise storage
saved_srs = self.state_store.load_state('sr')
@@ -199,12 +209,10 @@ class XendNode:
- def network_create(self, name_label, name_description, persist = True,
- net_uuid = None):
+ def network_create(self, record, persist = True, net_uuid = None):
if net_uuid is None:
net_uuid = uuid.createString()
- self.networks[net_uuid] = XendNetwork(net_uuid, name_label,
- name_description)
+ self.networks[net_uuid] = XendNetwork(net_uuid, record)
if persist:
self.save_networks()
return net_uuid
@@ -280,7 +288,7 @@ class XendNode:
self.state_store.save_state('pif', pif_records)
def save_networks(self):
- net_records = dict([(k, v.get_record(transient = False))
+ net_records = dict([(k, v.get_record_internal(False))
for k, v in self.networks.items()])
self.state_store.save_state('network', net_records)
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendOptions.py
--- a/tools/python/xen/xend/XendOptions.py Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendOptions.py Fri Mar 30 17:18:42 2007 -0600
@@ -165,7 +165,13 @@ class XendOptions:
def get_xend_tcp_xmlrpc_server_address(self):
return self.get_config_string("xend-tcp-xmlrpc-server-address",
-
self.xend_tcp_xmlrpc_server_address_default)
+
self.xend_tcp_xmlrpc_server_address_default)
+
+ def get_xend_tcp_xmlrpc_server_ssl_key_file(self):
+ return self.get_config_string("xend-tcp-xmlrpc-server-ssl-key-file")
+
+ def get_xend_tcp_xmlrpc_server_ssl_cert_file(self):
+ return self.get_config_string("xend-tcp-xmlrpc-server-ssl-cert-file")
def get_xend_unix_xmlrpc_server(self):
return self.get_config_bool("xend-unix-xmlrpc-server",
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendPIFMetrics.py
--- a/tools/python/xen/xend/XendPIFMetrics.py Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendPIFMetrics.py Fri Mar 30 17:18:42 2007 -0600
@@ -39,11 +39,13 @@ class XendPIFMetrics:
return pifs_util[pifname][n]
return 0.0
+ def get_last_updated(self):
+ import xen.xend.XendAPI as XendAPI
+ return XendAPI.now()
+
def get_record(self):
- import xen.xend.XendAPI as XendAPI
return {'uuid' : self.uuid,
- 'PIF' : self.pif.uuid,
'io_read_kbs' : self.get_io_read_kbs(),
'io_write_kbs' : self.get_io_write_kbs(),
- 'last_updated' : XendAPI.now(),
+ 'last_updated' : self.get_last_updated(),
}
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendStateStore.py
--- a/tools/python/xen/xend/XendStateStore.py Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendStateStore.py Fri Mar 30 17:18:42 2007 -0600
@@ -126,6 +126,13 @@ class XendStateStore:
if val_name not in cls_dict:
cls_dict[val_name] = {}
cls_dict[val_name][val_uuid] = None
+ elif val_type == '':
+ # dictionary
+ k = val_elem.getAttribute('key').encode('utf8')
+ v = val_elem.getAttribute('value').encode('utf8')
+ if val_name not in cls_dict:
+ cls_dict[val_name] = {}
+ cls_dict[val_name][k] = v
elif val_type == 'string':
cls_dict[val_name] = val_text.encode('utf8')
elif val_type == 'float':
@@ -197,7 +204,11 @@ class XendStateStore:
if type(val) == dict:
for val_uuid in val.keys():
val_node = doc.createElement(key)
- val_node.setAttribute('uuid', val_uuid)
+ if key == 'other_config':
+ val_node.setAttribute('key', str(val_uuid))
+ val_node.setAttribute('value', str(val[val_uuid]))
+ else:
+ val_node.setAttribute('uuid', val_uuid)
node.appendChild(val_node)
elif type(val) in (list, tuple):
for val_uuid in val:
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/XendVMMetrics.py
--- a/tools/python/xen/xend/XendVMMetrics.py Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/XendVMMetrics.py Fri Mar 30 17:18:42 2007 -0600
@@ -92,7 +92,7 @@ class XendVMMetrics:
set_flag('blocked')
set_flag('online')
set_flag('running')
- vcpus_flags[i] = ",".join(flags)
+ vcpus_flags[i] = flags
return vcpus_flags
else:
return {}
@@ -115,7 +115,7 @@ class XendVMMetrics:
addState("dying")
addState("crashed")
addState("shutdown")
- return ",".join(states)
+ return states
except Exception, err:
# ignore missing domain
log.trace("domain_getinfo(%d) failed, ignoring: %s", domid,
str(err))
@@ -140,8 +140,11 @@ class XendVMMetrics:
def get_start_time(self):
return self.xend_domain_instance.info.get("start_time", -1)
+ def get_last_updated(self):
+ import xen.xend.XendAPI as XendAPI
+ return XendAPI.now()
+
def get_record(self):
- import xen.xend.XendAPI as XendAPI
return { 'uuid' : self.uuid,
'memory_actual' : self.get_memory_actual(),
'VCPUs_number' : self.get_VCPUs_number(),
@@ -151,5 +154,5 @@ class XendVMMetrics:
'VCPUs_params' : self.get_VCPUs_params(),
'start_time' : self.get_start_time(),
'state' : self.get_state(),
- 'last_updated' : XendAPI.now(),
+ 'last_updated' : self.get_last_updated(),
}
diff -r e7da2fcb7a22 -r fc9e2f7920c9
tools/python/xen/xend/server/SSLXMLRPCServer.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xend/server/SSLXMLRPCServer.py Fri Mar 30 17:18:42
2007 -0600
@@ -0,0 +1,103 @@
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#============================================================================
+# Copyright (C) 2007 XenSource Inc.
+#============================================================================
+
+
+"""
+HTTPS wrapper for an XML-RPC server interface. Requires PyOpenSSL (Debian
+package python-pyopenssl).
+"""
+
+import socket
+
+from OpenSSL import SSL
+
+from xen.util.xmlrpclib2 import XMLRPCRequestHandler, TCPXMLRPCServer
+
+
+class SSLXMLRPCRequestHandler(XMLRPCRequestHandler):
+ def setup(self):
+ self.connection = self.request
+ self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
+ self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
+
+#
+# Taken from pyOpenSSL-0.6 examples (public-domain)
+#
+
+class SSLWrapper:
+ """
+ """
+ def __init__(self, conn):
+ """
+ Connection is not yet a new-style class,
+ so I'm making a proxy instead of subclassing.
+ """
+ self.__dict__["conn"] = conn
+ def __getattr__(self, name):
+ return getattr(self.__dict__["conn"], name)
+ def __setattr__(self, name, value):
+ setattr(self.__dict__["conn"], name, value)
+
+ def close(self):
+ self.shutdown()
+ return self.__dict__["conn"].close()
+
+ def shutdown(self, how=1):
+ """
+ SimpleXMLRpcServer.doPOST calls shutdown(1),
+ and Connection.shutdown() doesn't take
+ an argument. So we just discard the argument.
+ """
+ # Block until the shutdown is complete
+ self.__dict__["conn"].shutdown()
+ self.__dict__["conn"].shutdown()
+
+ def accept(self):
+ """
+ This is the other part of the shutdown() workaround.
+ Since servers create new sockets, we have to infect
+ them with our magic. :)
+ """
+ c, a = self.__dict__["conn"].accept()
+ return (SSLWrapper(c), a)
+
+#
+# End of pyOpenSSL-0.6 example code.
+#
+
+class SSLXMLRPCServer(TCPXMLRPCServer):
+ def __init__(self, addr, allowed, xenapi, logRequests = 1,
+ ssl_key_file = None, ssl_cert_file = None):
+
+ TCPXMLRPCServer.__init__(self, addr, allowed, xenapi,
+ SSLXMLRPCRequestHandler, logRequests)
+
+ if not ssl_key_file or not ssl_cert_file:
+ raise ValueError("SSLXMLRPCServer requires ssl_key_file "
+ "and ssl_cert_file to be set.")
+
+ # make a SSL socket
+ ctx = SSL.Context(SSL.SSLv23_METHOD)
+ ctx.set_options(SSL.OP_NO_SSLv2)
+ ctx.use_privatekey_file (ssl_key_file)
+ ctx.use_certificate_file(ssl_cert_file)
+ self.socket = SSLWrapper(SSL.Connection(ctx,
+ socket.socket(self.address_family,
+ self.socket_type)))
+ self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+ self.server_bind()
+ self.server_activate()
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/server/SrvDaemon.py
--- a/tools/python/xen/xend/server/SrvDaemon.py Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/server/SrvDaemon.py Fri Mar 30 17:18:42 2007 -0600
@@ -38,7 +38,8 @@ class Daemon:
self.traceon = False
self.tracefile = None
self.traceindent = 0
- self.child = 0
+ self.child = 0
+ self.traceLock = threading.Lock()
def cleanup_xend(self, kill):
@@ -253,6 +254,7 @@ class Daemon:
pass
def print_trace(self, string):
+ self.tracefile.write("%s: "% threading.currentThread().getName())
for i in range(self.traceindent):
ch = " "
if (i % 5):
@@ -263,50 +265,54 @@ class Daemon:
self.tracefile.write(string)
def trace(self, frame, event, arg):
- if not self.traceon:
- print >>self.tracefile
- print >>self.tracefile, '-' * 20, 'TRACE OFF', '-' * 20
- self.tracefile.close()
- self.tracefile = None
- return None
- if event == 'call':
- code = frame.f_code
- filename = code.co_filename
- m = re.search('.*xend/(.*)', filename)
- if not m:
+ self.traceLock.acquire()
+ try:
+ if not self.traceon:
+ print >>self.tracefile
+ print >>self.tracefile, '-' * 20, 'TRACE OFF', '-' * 20
+ self.tracefile.close()
+ self.tracefile = None
return None
- modulename = m.group(1)
- if modulename.endswith('.pyc'):
- modulename = modulename[:-1]
- if modulename == 'sxp.py' or \
- modulename == 'XendLogging.py' or \
- modulename == 'XendMonitor.py' or \
- modulename == 'server/SrvServer.py':
- return None
- self.traceindent += 1
- self.print_trace("> %s:%s\n"
- % (modulename, code.co_name))
- elif event == 'line':
- filename = frame.f_code.co_filename
- lineno = frame.f_lineno
- self.print_trace("%4d %s" %
- (lineno, linecache.getline(filename, lineno)))
- elif event == 'return':
- code = frame.f_code
- filename = code.co_filename
- m = re.search('.*xend/(.*)', filename)
- if not m:
- return None
- modulename = m.group(1)
- self.print_trace("< %s:%s\n"
- % (modulename, code.co_name))
- self.traceindent -= 1
- elif event == 'exception':
- self.print_trace("! Exception:\n")
- (ex, val, tb) = arg
- traceback.print_exception(ex, val, tb, 10, self.tracefile)
- #del tb
- return self.trace
+ if event == 'call':
+ code = frame.f_code
+ filename = code.co_filename
+ m = re.search('.*xend/(.*)', filename)
+ if not m:
+ return None
+ modulename = m.group(1)
+ if modulename.endswith('.pyc'):
+ modulename = modulename[:-1]
+ if modulename == 'sxp.py' or \
+ modulename == 'XendLogging.py' or \
+ modulename == 'XendMonitor.py' or \
+ modulename == 'server/SrvServer.py':
+ return None
+ self.traceindent += 1
+ self.print_trace("> %s:%s\n"
+ % (modulename, code.co_name))
+ elif event == 'line':
+ filename = frame.f_code.co_filename
+ lineno = frame.f_lineno
+ self.print_trace("%4d %s" %
+ (lineno, linecache.getline(filename, lineno)))
+ elif event == 'return':
+ code = frame.f_code
+ filename = code.co_filename
+ m = re.search('.*xend/(.*)', filename)
+ if not m:
+ return None
+ modulename = m.group(1)
+ self.print_trace("< %s:%s\n"
+ % (modulename, code.co_name))
+ self.traceindent -= 1
+ elif event == 'exception':
+ self.print_trace("! Exception:\n")
+ (ex, val, tb) = arg
+ traceback.print_exception(ex, val, tb, 10, self.tracefile)
+ #del tb
+ return self.trace
+ finally:
+ self.traceLock.release()
def set_user(self):
# Set the UID.
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xend/server/SrvServer.py
--- a/tools/python/xen/xend/server/SrvServer.py Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xend/server/SrvServer.py Fri Mar 30 17:18:42 2007 -0600
@@ -52,6 +52,7 @@ from xen.xend import Vifctl
from xen.xend import Vifctl
from xen.xend.XendLogging import log
from xen.xend.XendClient import XEN_API_SOCKET
+from xen.xend.XendDomain import instance as xenddomain
from xen.web.SrvDir import SrvDir
from SrvRoot import SrvRoot
@@ -72,7 +73,7 @@ class XendServers:
def add(self, server):
self.servers.append(server)
- def cleanup(self, signum = 0, frame = None):
+ def cleanup(self, signum = 0, frame = None, reloading = False):
log.debug("SrvServer.cleanup()")
self.cleaningUp = True
for server in self.servers:
@@ -80,12 +81,18 @@ class XendServers:
server.shutdown()
except:
pass
+
+ # clean up domains for those that have on_xend_stop
+ if not reloading:
+ xenddomain().cleanup_domains()
+
self.running = False
+
def reloadConfig(self, signum = 0, frame = None):
log.debug("SrvServer.reloadConfig()")
self.reloadingConfig = True
- self.cleanup(signum, frame)
+ self.cleanup(signum, frame, reloading = True)
def start(self, status):
# Running the network script will spawn another process, which takes
@@ -144,6 +151,12 @@ class XendServers:
status.close()
status = None
+ # Reaching this point means we can auto start domains
+ try:
+ xenddomain().autostart_domains()
+ except Exception, e:
+ log.exception("Failed while autostarting domains")
+
# loop to keep main thread alive until it receives a SIGTERM
self.running = True
while self.running:
@@ -172,33 +185,49 @@ def _loadConfig(servers, root, reload):
api_cfg = xoptions.get_xen_api_server()
if api_cfg:
try:
- addrs = [(str(x[0]).split(':'),
- len(x) > 1 and x[1] or XendAPI.AUTH_PAM,
- len(x) > 2 and x[2] and map(re.compile, x[2].split(" "))
- or None)
- for x in api_cfg]
- for addrport, auth, allowed in addrs:
- if auth not in [XendAPI.AUTH_PAM, XendAPI.AUTH_NONE]:
- log.error('Xen-API server configuration %s is invalid, ' +
- 'as %s is not a valid authentication type.',
- api_cfg, auth)
- break
-
- if len(addrport) == 1:
- if addrport[0] == 'unix':
- servers.add(XMLRPCServer(auth, True,
- path = XEN_API_SOCKET,
- hosts_allowed = allowed))
+ for server_cfg in api_cfg:
+ # Parse the xen-api-server config
+
+ ssl_key_file = None
+ ssl_cert_file = None
+ auth_method = XendAPI.AUTH_NONE
+ hosts_allowed = None
+
+ host_addr = server_cfg[0].split(':', 1)
+ if len(host_addr) == 1:
+ if host_addr[0].lower() == 'unix':
+ use_tcp = False
+ host = 'localhost'
+ port = 0
else:
- servers.add(
- XMLRPCServer(auth, True, True, '',
- int(addrport[0]),
- hosts_allowed = allowed))
+ use_tcp = True
+ host = ''
+ port = int(host_addr[0])
else:
- addr, port = addrport
- servers.add(XMLRPCServer(auth, True, True, addr,
- int(port),
- hosts_allowed = allowed))
+ use_tcp = True
+ host = str(host_addr[0])
+ port = int(host_addr[1])
+
+ if len(server_cfg) > 1:
+ if server_cfg[1] in [XendAPI.AUTH_PAM, XendAPI.AUTH_NONE]:
+ auth_method = server_cfg[1]
+
+ if len(server_cfg) > 2:
+ hosts_allowed = server_cfg[2] or None
+
+ if len(server_cfg) > 4:
+ # SSL key and cert file
+ ssl_key_file = server_cfg[3]
+ ssl_cert_file = server_cfg[4]
+
+
+ servers.add(XMLRPCServer(auth_method, True, use_tcp = use_tcp,
+ ssl_key_file = ssl_key_file,
+ ssl_cert_file = ssl_cert_file,
+ host = host, port = port,
+ path = XEN_API_SOCKET,
+ hosts_allowed = hosts_allowed))
+
except (ValueError, TypeError), exn:
log.exception('Xen API Server init failed')
log.error('Xen-API server configuration %s is invalid.', api_cfg)
@@ -206,8 +235,17 @@ def _loadConfig(servers, root, reload):
if xoptions.get_xend_tcp_xmlrpc_server():
addr = xoptions.get_xend_tcp_xmlrpc_server_address()
port = xoptions.get_xend_tcp_xmlrpc_server_port()
- servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False, use_tcp = True,
- host = addr, port = port))
+ ssl_key_file = xoptions.get_xend_tcp_xmlrpc_server_ssl_key_file()
+ ssl_cert_file = xoptions.get_xend_tcp_xmlrpc_server_ssl_cert_file()
+
+ if ssl_key_file and ssl_cert_file:
+ servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False, use_tcp = True,
+ ssl_key_file = ssl_key_file,
+ ssl_cert_file = ssl_cert_file,
+ host = addr, port = port))
+ else:
+ servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False, use_tcp = True,
+ host = addr, port = port))
if xoptions.get_xend_unix_xmlrpc_server():
servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False))
diff -r e7da2fcb7a22 -r fc9e2f7920c9
tools/python/xen/xend/server/XMLRPCServer.py
--- a/tools/python/xen/xend/server/XMLRPCServer.py Fri Mar 30 10:27:15
2007 -0600
+++ b/tools/python/xen/xend/server/XMLRPCServer.py Fri Mar 30 17:18:42
2007 -0600
@@ -21,6 +21,11 @@ import types
import types
import xmlrpclib
from xen.util.xmlrpclib2 import UnixXMLRPCServer, TCPXMLRPCServer
+try:
+ from SSLXMLRPCServer import SSLXMLRPCServer
+ ssl_enabled = True
+except ImportError:
+ ssl_enabled = False
from xen.xend import XendAPI, XendDomain, XendDomainInfo, XendNode
from xen.xend import XendLogging, XendDmesg
@@ -87,14 +92,20 @@ exclude = ['domain_create', 'domain_rest
exclude = ['domain_create', 'domain_restore']
class XMLRPCServer:
- def __init__(self, auth, use_xenapi, use_tcp=False, host = "localhost",
- port = 8006, path = XML_RPC_SOCKET, hosts_allowed = None):
+ def __init__(self, auth, use_xenapi, use_tcp = False,
+ ssl_key_file = None, ssl_cert_file = None,
+ host = "localhost", port = 8006, path = XML_RPC_SOCKET,
+ hosts_allowed = None):
+
self.use_tcp = use_tcp
self.port = port
self.host = host
self.path = path
self.hosts_allowed = hosts_allowed
+ self.ssl_key_file = ssl_key_file
+ self.ssl_cert_file = ssl_cert_file
+
self.ready = False
self.running = True
self.auth = auth
@@ -107,14 +118,32 @@ class XMLRPCServer:
try:
if self.use_tcp:
- log.info("Opening TCP XML-RPC server on %s%d%s",
+ using_ssl = self.ssl_key_file and self.ssl_cert_file
+
+ log.info("Opening %s XML-RPC server on %s%d%s",
+ using_ssl and 'HTTPS' or 'TCP',
self.host and '%s:' % self.host or
'all interfaces, port ',
self.port, authmsg)
- self.server = TCPXMLRPCServer((self.host, self.port),
- self.hosts_allowed,
- self.xenapi is not None,
- logRequests = False)
+
+ if using_ssl:
+ if not ssl_enabled:
+ raise ValueError("pyOpenSSL not installed. "
+ "Unable to start HTTPS XML-RPC
server")
+ self.server = SSLXMLRPCServer(
+ (self.host, self.port),
+ self.hosts_allowed,
+ self.xenapi is not None,
+ logRequests = False,
+ ssl_key_file = self.ssl_key_file,
+ ssl_cert_file = self.ssl_cert_file)
+ else:
+ self.server = TCPXMLRPCServer(
+ (self.host, self.port),
+ self.hosts_allowed,
+ self.xenapi is not None,
+ logRequests = False)
+
else:
log.info("Opening Unix domain socket XML-RPC server on %s%s",
self.path, authmsg)
@@ -126,7 +155,12 @@ class XMLRPCServer:
ready = True
running = False
return
-
+ except Exception, e:
+ log.exception('Cannot start server: %s!', e)
+ ready = True
+ running = False
+ return
+
# Register Xen API Functions
# -------------------------------------------------------------------
# exportable functions are ones that do not begin with '_'
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xm/XenAPI.py
--- a/tools/python/xen/xm/XenAPI.py Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xm/XenAPI.py Fri Mar 30 17:18:42 2007 -0600
@@ -12,7 +12,7 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
-# Copyright (C) 2006 XenSource Inc.
+# Copyright (C) 2006-2007 XenSource Inc.
#============================================================================
#
# Parts of this file are based upon xmlrpclib.py, the XML-RPC client
@@ -47,7 +47,7 @@ import gettext
import gettext
import xmlrpclib
-import xen.util.xmlrpclib2
+import xen.util.xmlrpcclient as xmlrpcclient
translation = gettext.translation('xen-xm', fallback = True)
@@ -85,7 +85,7 @@ _RECONNECT_AND_RETRY = (lambda _ : ())
_RECONNECT_AND_RETRY = (lambda _ : ())
-class Session(xen.util.xmlrpclib2.ServerProxy):
+class Session(xmlrpcclient.ServerProxy):
"""A server proxy and session manager for communicating with Xend using
the Xen-API.
@@ -104,13 +104,15 @@ class Session(xen.util.xmlrpclib2.Server
def __init__(self, uri, transport=None, encoding=None, verbose=0,
allow_none=1):
- xen.util.xmlrpclib2.ServerProxy.__init__(self, uri, transport,
- encoding, verbose,
- allow_none)
+ xmlrpcclient.ServerProxy.__init__(self, uri, transport, encoding,
+ verbose, allow_none)
self._session = None
self.last_login_method = None
self.last_login_params = None
+
+ def getSession(self):
+ return self._session
def xenapi_request(self, methodname, params):
if methodname.startswith('login'):
@@ -150,7 +152,7 @@ class Session(xen.util.xmlrpclib2.Server
elif name.startswith('login'):
return lambda *params: self._login(name, params)
else:
- return xen.util.xmlrpclib2.ServerProxy.__getattr__(self, name)
+ return xmlrpcclient.ServerProxy.__getattr__(self, name)
def _parse_result(result):
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xm/create.dtd
--- a/tools/python/xen/xm/create.dtd Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xm/create.dtd Fri Mar 30 17:18:42 2007 -0600
@@ -37,6 +37,8 @@
memory,
vbd*,
vif*,
+ console*,
+ platform*,
vcpu_param*,
other_config*)>
<!ATTLIST vm is_a_template CDATA #REQUIRED
@@ -46,11 +48,6 @@
actions_after_shutdown %NORMAL_EXIT; #REQUIRED
actions_after_reboot %NORMAL_EXIT; #REQUIRED
actions_after_crash %CRASH_BEHAVIOUR; #REQUIRED
- platform_std_VGA CDATA #REQUIRED
- platform_serial CDATA #REQUIRED
- platform_localtime CDATA #REQUIRED
- platform_clock_offet CDATA #REQUIRED
- platform_enable_audio CDATA #REQUIRED
PCI_bus CDATA #REQUIRED>
<!ELEMENT memory EMPTY>
@@ -74,8 +71,10 @@
mtu CDATA #REQUIRED
device CDATA #REQUIRED
qos_algorithm_type CDATA #REQUIRED
- bridge CDATA #IMPLIED
network CDATA #IMPLIED>
+
+<!ELEMENT console (other_config*)>
+<!ATTLIST console protocol (vt100|rfb|rdp) #REQUIRED>
<!ELEMENT pv EMPTY>
<!ATTLIST pv kernel CDATA #REQUIRED
@@ -105,13 +104,17 @@
<!ELEMENT label (#PCDATA)>
<!ELEMENT description (#PCDATA)>
+<!ELEMENT platform EMPTY>
+<!ATTLIST platform key CDATA #REQUIRED
+ value CDATA #REQUIRED>
+
<!ELEMENT vcpu_param EMPTY>
<!ATTLIST vcpu_param key CDATA #REQUIRED
value CDATA #REQUIRED>
<!ELEMENT other_config EMPTY>
<!ATTLIST other_config key CDATA #REQUIRED
- value CDATA #REQUIRED>
+ value CDATA #REQUIRED>
<!ELEMENT qos_algorithm_param EMPTY>
<!ATTLIST qos_algorithm_param key CDATA #REQUIRED
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xm/create.py Fri Mar 30 17:18:42 2007 -0600
@@ -103,6 +103,11 @@ gopts.opt('xmldryrun', short='x',
fn=set_true, default=0,
use="XML dry run - prints the resulting configuration in XML but "
"does not create the domain.")
+
+gopts.opt('skipdtd', short='s',
+ fn=set_true, default=0,
+ use="Skip DTD checking - skips checks on XML before creating. "
+ " Experimental. Can decrease create time." )
gopts.opt('paused', short='p',
fn=set_true, default=0,
@@ -1098,6 +1103,8 @@ def parseCommandLine(argv):
if not gopts.vals.xauthority:
gopts.vals.xauthority = get_xauthority()
+ gopts.is_xml = False
+
# Process remaining args as config variables.
for arg in args:
if '=' in arg:
@@ -1106,11 +1113,16 @@ def parseCommandLine(argv):
if gopts.vals.config:
config = gopts.vals.config
else:
- gopts.load_defconfig()
- preprocess(gopts.vals)
- if not gopts.getopt('name') and gopts.getopt('defconfig'):
- gopts.setopt('name', os.path.basename(gopts.getopt('defconfig')))
- config = make_config(gopts.vals)
+ try:
+ gopts.load_defconfig()
+ preprocess(gopts.vals)
+ if not gopts.getopt('name') and gopts.getopt('defconfig'):
+ gopts.setopt('name',
os.path.basename(gopts.getopt('defconfig')))
+ config = make_config(gopts.vals)
+ except XMLFileError, ex:
+ XMLFile = ex.getFile()
+ gopts.is_xml = True
+ config = ex.getFile()
return (gopts, config)
@@ -1233,6 +1245,8 @@ def help():
return str(gopts)
def main(argv):
+ is_xml = False
+
try:
(opts, config) = parseCommandLine(argv)
except StandardError, ex:
@@ -1241,23 +1255,24 @@ def main(argv):
if not opts:
return
- if type(config) == str:
- try:
- config = sxp.parse(file(config))[0]
- except IOError, exn:
- raise OptionError("Cannot read file %s: %s" % (config, exn[1]))
-
- if serverType == SERVER_XEN_API:
- from xen.xm.xenapi_create import sxp2xml
- sxp2xml_inst = sxp2xml()
- doc = sxp2xml_inst.convert_sxp_to_xml(config, transient=True)
-
- if opts.vals.dryrun:
- SXPPrettyPrint.prettyprint(config)
-
- if opts.vals.xmldryrun and serverType == SERVER_XEN_API:
- from xml.dom.ext import PrettyPrint as XMLPrettyPrint
- XMLPrettyPrint(doc)
+ if not opts.is_xml:
+ if type(config) == str:
+ try:
+ config = sxp.parse(file(config))[0]
+ except IOError, exn:
+ raise OptionError("Cannot read file %s: %s" % (config, exn[1]))
+
+ if serverType == SERVER_XEN_API:
+ from xen.xm.xenapi_create import sxp2xml
+ sxp2xml_inst = sxp2xml()
+ doc = sxp2xml_inst.convert_sxp_to_xml(config, transient=True)
+
+ if opts.vals.dryrun and not opts.is_xml:
+ SXPPrettyPrint.prettyprint(config)
+
+ if opts.vals.xmldryrun and serverType == SERVER_XEN_API:
+ from xml.dom.ext import PrettyPrint as XMLPrettyPrint
+ XMLPrettyPrint(doc)
if opts.vals.dryrun or opts.vals.xmldryrun:
return
@@ -1268,10 +1283,15 @@ def main(argv):
if serverType == SERVER_XEN_API:
from xen.xm.xenapi_create import xenapi_create
xenapi_create_inst = xenapi_create()
- vm_refs = xenapi_create_inst.create(document = doc)
+ if opts.is_xml:
+ vm_refs = xenapi_create_inst.create(filename = config,
+ skipdtd = opts.vals.skipdtd)
+ else:
+ vm_refs = xenapi_create_inst.create(document = doc,
+ skipdtd = opts.vals.skipdtd)
map(lambda vm_ref: server.xenapi.VM.start(vm_ref, 0), vm_refs)
- else:
+ elif not opts.is_xml:
if not create_security_check(config):
raise security.ACMError(
'Security Configuration prevents domain from starting')
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xm/main.py Fri Mar 30 17:18:42 2007 -0600
@@ -49,7 +49,7 @@ from xen.xend.XendConstants import *
from xen.xm.opts import OptionError, Opts, wrap, set_true
from xen.xm import console
-from xen.util.xmlrpclib2 import ServerProxy
+from xen.util.xmlrpcclient import ServerProxy
import XenAPI
@@ -345,7 +345,8 @@ acm_commands = [
]
all_commands = (domain_commands + host_commands + scheduler_commands +
- device_commands + vnet_commands + acm_commands + ['shell'])
+ device_commands + vnet_commands + acm_commands +
+ ['shell', 'event-monitor'])
##
@@ -559,11 +560,21 @@ def get_single_vm(dom):
def get_single_vm(dom):
if serverType == SERVER_XEN_API:
uuids = server.xenapi.VM.get_by_name_label(dom)
- n = len(uuids)
- if n > 0:
+ if len(uuids) > 0:
return uuids[0]
- else:
- raise OptionError("Domain '%s' not found." % dom)
+
+ try:
+ domid = int(dom)
+ uuids = [server.xenapi.VM.get_domid(vm_ref)
+ for vm_ref in server.xenapi.VM.get_all()
+ if int(server.xenapi.VM.get_domid(vm_ref)) == domid]
+ except:
+ pass
+
+ if len(uuids) > 0:
+ return uuids[0]
+
+ raise OptionError("Domain '%s' not found." % dom)
else:
dominfo = server.xend.domain(dom, False)
return dominfo['uuid']
@@ -633,6 +644,17 @@ def xm_shell(args):
Shell().cmdloop('The Xen Master. Type "help" for a list of functions.')
+def xm_event_monitor(args):
+ if serverType == SERVER_XEN_API:
+ while True:
+ server.xenapi.event.register(args)
+ events = server.xenapi.event.next()
+ for e in events:
+ print e
+ else:
+ err("Event monitoring not supported unless using Xen-API.")
+
+
#########################################################################
#
# Main xm functions
@@ -722,7 +744,7 @@ def getDomains(domain_names, state, full
states = ('running', 'blocked', 'paused', 'shutdown',
'crashed', 'dying')
def state_on_off(state):
- if dom_metrics['state'].find(state) > -1:
+ if state in dom_metrics['state']:
return state[0]
else:
return "-"
@@ -850,7 +872,8 @@ def parse_doms_info(info):
def check_sched_type(sched):
if serverType == SERVER_XEN_API:
- current =
server.xenapi.host.get_sched_policy(server.xenapi.session.get_this_host())
+ current = server.xenapi.host.get_sched_policy(
+ server.xenapi.session.get_this_host(server.getSession()))
else:
current = 'unknown'
for x in server.xend.node.info()[1:]:
@@ -952,12 +975,10 @@ def xm_vcpu_list(args):
['name', vm_records[vm_ref]['name_label']],
['vcpu_count', vm_records[vm_ref]['VCPUs_max']]]
-
-
for i in range(int(vm_records[vm_ref]['VCPUs_max'])):
def chk_flag(flag):
- return vm_metrics[vm_ref]['VCPUs_flags'][str(i)] \
- .find(flag) > -1 and 1 or 0
+ return flag in vm_metrics[vm_ref]['VCPUs_flags'][str(i)] \
+ and 1 or 0
vcpu_info = ['vcpu',
['number',
@@ -1044,7 +1065,7 @@ def xm_vcpu_list(args):
if serverType == SERVER_XEN_API:
nr_cpus = len(server.xenapi.host.get_host_CPUs(
- server.xenapi.session.get_this_host()))
+ server.xenapi.session.get_this_host(server.getSession())))
else:
for x in server.xend.node.info()[1:]:
if len(x) > 1 and x[0] == 'nr_cpus':
@@ -1260,8 +1281,9 @@ def xm_vcpu_pin(args):
cpumap = cpu_make_map(args[2])
if serverType == SERVER_XEN_API:
+ cpumap = map(str, cpumap)
server.xenapi.VM.add_to_VCPUs_params_live(
- get_single_vm(dom), "cpumap%i" % vcpu, ",".join(cpumap))
+ get_single_vm(dom), "cpumap%i" % int(vcpu), ",".join(cpumap))
else:
server.xend.domain.pincpu(dom, vcpu, cpumap)
@@ -1509,7 +1531,7 @@ def xm_info(args):
# Need to fake out old style xm info as people rely on parsing it
host_record = server.xenapi.host.get_record(
- server.xenapi.session.get_this_host())
+ server.xenapi.session.get_this_host(server.getSession()))
host_cpu_records = map(server.xenapi.host_cpu.get_record,
host_record["host_CPUs"])
@@ -1686,7 +1708,7 @@ def xm_debug_keys(args):
if serverType == SERVER_XEN_API:
server.xenapi.host.send_debug_keys(
- server.xenapi.session.get_this_host(),
+ server.xenapi.session.get_this_host(server.getSession()),
keys)
else:
server.xend.node.send_debug_keys(keys)
@@ -1715,7 +1737,7 @@ def xm_dmesg(args):
usage('dmesg')
if serverType == SERVER_XEN_API:
- host = server.xenapi.session.get_this_host()
+ host = server.xenapi.session.get_this_host(server.getSession())
if use_clear:
print server.xenapi.host.dmesg_clear(host),
else:
@@ -1731,7 +1753,7 @@ def xm_log(args):
if serverType == SERVER_XEN_API:
print server.xenapi.host.get_log(
- server.xenapi.session.get_this_host())
+ server.xenapi.session.get_this_host(server.getSession()))
else:
print server.xend.node.log()
@@ -2169,6 +2191,7 @@ def xm_vnet_delete(args):
commands = {
"shell": xm_shell,
+ "event-monitor": xm_event_monitor,
# console commands
"console": xm_console,
# xenstat commands
@@ -2371,11 +2394,10 @@ def _run_cmd(cmd, cmd_name, args):
if isinstance(e, security.ACMError):
err(str(e))
return False, 1
- else:
- print "Unexpected error:", sys.exc_info()[0]
- print
- print "Please report to xen-devel@xxxxxxxxxxxxxxxxxxx"
- raise
+ print "Unexpected error:", sys.exc_info()[0]
+ print
+ print "Please report to xen-devel@xxxxxxxxxxxxxxxxxxx"
+ raise
return False, 1
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xm/messages/en/xen-xm.po
--- a/tools/python/xen/xm/messages/en/xen-xm.po Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xm/messages/en/xen-xm.po Fri Mar 30 17:18:42 2007 -0600
@@ -19,7 +19,7 @@ msgid ""
msgid ""
msgstr ""
"Project-Id-Version: Xen-xm 3.0\n"
-"PO-Revision-Date: 2007-03-10 23:17+0000\n"
+"PO-Revision-Date: 2007-03-29 16:13+0100\n"
"Last-Translator: Ewan Mellor <ewan@xxxxxxxxxxxxx>\n"
"Language-Team: xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxx>\n"
"MIME-Version: 1.0\n"
@@ -64,3 +64,6 @@ msgstr "The VM must be %(2)s to perform
msgid "VM_HVM_REQUIRED"
msgstr "HVM guest support is unavailable: is VT/AMD-V supported by your CPU
and enabled in your BIOS?"
+
+msgid "SESSION_NOT_REGISTERED"
+msgstr "This session is not registered to receive events. You must call
event.register before event.next. (Session handle is %(1)s.)"
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xm/opts.py
--- a/tools/python/xen/xm/opts.py Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xm/opts.py Fri Mar 30 17:18:42 2007 -0600
@@ -24,6 +24,8 @@ import sys
import sys
import types
+
+
def _line_wrap(text, width = 70):
lines = []
current_line = ''
@@ -59,6 +61,15 @@ class OptionError(Exception):
self.usage = usage
def __str__(self):
return self.message
+
+class XMLFileError(Exception):
+ """Thrown is input is an XML File"""
+ def __init__(self, XMLFile):
+ self.XMLFile = XMLFile
+ def __str__(self):
+ return "XMLFileError: %s" % self.XMLFile
+ def getFile(self):
+ return self.XMLFile
class Opt:
"""An individual option.
@@ -492,6 +503,14 @@ class Opts:
p = os.path.join(os.path.curdir, p)
if os.path.exists(p):
self.info('Using config file "%s".' % p)
+
+ f = open(p)
+ is_xml = (f.read(1) == '<')
+ f.close()
+
+ if is_xml:
+ raise XMLFileError(p)
+
self.load(p, help)
break
else:
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/python/xen/xm/xenapi_create.py
--- a/tools/python/xen/xm/xenapi_create.py Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/python/xen/xm/xenapi_create.py Fri Mar 30 17:18:42 2007 -0600
@@ -25,7 +25,7 @@ from xen.xend import sxp
from xen.xend import sxp
from xen.xend.XendAPIConstants import XEN_API_ON_NORMAL_EXIT, \
XEN_API_ON_CRASH_BEHAVIOUR
-
+from xen.xm.opts import OptionError
import sys
import os
@@ -75,15 +75,20 @@ class xenapi_create:
self.dtd = "/usr/lib/python/xen/xm/create.dtd"
- def create(self, filename=None, document=None):
+ def create(self, filename=None, document=None, skipdtd=False):
"""
Create a domain from an XML file or DOM tree
"""
+ if skipdtd:
+ print "Skipping DTD checks. Dangerous!"
+
if filename is not None:
- self.check_dtd(file)
- document = parse(file)
+ if not skipdtd:
+ self.check_dtd(filename)
+ document = parse(filename)
elif document is not None:
- self.check_dom_against_dtd(document)
+ if not skipdtd:
+ self.check_dom_against_dtd(document)
self.check_doc(document)
@@ -179,15 +184,7 @@ class xenapi_create:
map(self.check_vif, vifs)
def check_vif(self, vif):
- """
- Check that the vif has
- either a bridge or network
- name but not both
- """
- if "bridge" in vif.attributes.keys() \
- and "network" in vif.attributes.keys():
- raise "You cannot specify both a bridge and\
- a network name."
+ pass
# Cleanup methods here
def cleanup_vdis(self, vdi_refs_dict):
@@ -265,18 +262,8 @@ class xenapi_create:
vm.attributes["actions_after_reboot"].value,
"actions_after_crash":
vm.attributes["actions_after_crash"].value,
- "platform_std_VGA":
- vm.attributes["platform_std_VGA"].value,
- "platform_serial":
- vm.attributes["platform_serial"].value,
- "platform_localtime":
- vm.attributes["platform_localtime"].value,
- "platform_clock_offet":
- vm.attributes["platform_clock_offet"].value,
- "platform_enable_audio":
- vm.attributes["platform_enable_audio"].value,
- "PCI_bus":
- vm.attributes["platform_enable_audio"].value,
+ "platform":
+ get_child_nodes_as_dict(vm, "platform", "key", "value"),
"other_config":
get_child_nodes_as_dict(vm, "other_config", "key", "value")
}
@@ -300,7 +287,7 @@ class xenapi_create:
"HVM_boot_policy":
get_child_node_attribute(vm, "hvm", "boot_policy"),
"HVM_boot_params":
- get_child_nodes_as_dict(hvm, "boot_params", "key", "value")
+ get_child_nodes_as_dict(hvm, "boot_param", "key", "value")
})
try:
vm_ref = server.xenapi.VM.create(vm_record)
@@ -308,19 +295,29 @@ class xenapi_create:
traceback.print_exc()
sys.exit(-1)
- # Now create vbds
-
- vbds = vm.getElementsByTagName("vbd")
-
- self.create_vbds(vm_ref, vbds, vdis)
-
- # Now create vifs
-
- vifs = vm.getElementsByTagName("vif")
-
- self.create_vifs(vm_ref, vifs)
-
- return vm_ref
+ try:
+ # Now create vbds
+
+ vbds = vm.getElementsByTagName("vbd")
+
+ self.create_vbds(vm_ref, vbds, vdis)
+
+ # Now create vifs
+
+ vifs = vm.getElementsByTagName("vif")
+
+ self.create_vifs(vm_ref, vifs)
+
+ # Now create consoles
+
+ consoles = vm.getElementsByTagName("console")
+
+ self.create_consoles(vm_ref, consoles)
+
+ return vm_ref
+ except:
+ server.xenapi.VM.destroy(vm_ref)
+ raise
def create_vbds(self, vm_ref, vbds, vdis):
log(DEBUG, "create_vbds")
@@ -358,13 +355,16 @@ class xenapi_create:
def create_vif(self, vm_ref, vif):
log(DEBUG, "create_vif")
- if "bridge" in vif.attributes.keys():
- raise "Not allowed to add by bridge just yet"
- elif "network" in vif.attributes.keys():
- network = [network_ref
+ if "network" in vif.attributes.keys():
+ networks = [network_ref
for network_ref in server.xenapi.network.get_all()
if server.xenapi.network.get_name_label(network_ref)
- == vif.attributes["network"].value][0]
+ == vif.attributes["network"].value]
+ if len(networks) > 0:
+ network = networks[0]
+ else:
+ raise OptionError("Network %s doesn't exist"
+ % vif.attributes["network"].value)
else:
network = self._get_network_ref()
@@ -397,6 +397,26 @@ class xenapi_create:
self._network_refs = server.xenapi.network.get_all()
return self._network_refs.pop(0)
+ def create_consoles(self, vm_ref, consoles):
+ log(DEBUG, "create_consoles")
+ return map(lambda console: self.create_console(vm_ref, console),
+ consoles)
+
+ def create_console(self, vm_ref, console):
+ log(DEBUG, "create_consoles")
+
+ console_record = {
+ "VM":
+ vm_ref,
+ "protocol":
+ console.attributes["protocol"].value,
+ "other_params":
+ get_child_nodes_as_dict(console,
+ "other_param", "key", "value")
+ }
+
+ return server.xenapi.console.create(console_record)
+
def get_child_by_name(exp, childname, default = None):
try:
return [child for child in sxp.children(exp)
@@ -460,11 +480,6 @@ class sxp2xml:
= actions_after_reboot
vm.attributes["actions_after_crash"] \
= actions_after_crash
- vm.attributes["platform_std_VGA"] = "false"
- vm.attributes["platform_serial"] = ""
- vm.attributes["platform_localtime"] = ""
- vm.attributes["platform_clock_offet"] = ""
- vm.attributes["platform_enable_audio"] = ""
vm.attributes["PCI_bus"] = ""
vm.attributes["vcpus_max"] \
@@ -502,7 +517,13 @@ class sxp2xml:
vm.appendChild(pv)
elif image[0] == "hvm":
hvm = document.createElement("hvm")
- hvm.attributes["boot_policy"] = ""
+ hvm.attributes["boot_policy"] = "BIOS order"
+
+ boot_order = document.createElement("boot_param")
+ boot_order.attributes["key"] = "order"
+ boot_order.attributes["value"] \
+ = get_child_by_name(image, "boot", "abcd")
+ hvm.appendChild
vm.appendChild(hvm)
@@ -535,6 +556,18 @@ class sxp2xml:
vifs = map(lambda vif: self.extract_vif(vif, document), vifs_sxp)
map(vm.appendChild, vifs)
+
+ # Last but not least the consoles...
+
+ consoles = self.extract_consoles(image, document)
+
+ map(vm.appendChild, consoles)
+
+ # Platform variables...
+
+ platform = self.extract_platform(image, document)
+
+ map(vm.appendChild, platform)
# transient?
@@ -626,13 +659,69 @@ class sxp2xml:
vif.attributes["qos_algorithm_type"] = ""
if get_child_by_name(vif_sxp, "bridge") is not None:
- vif.attributes["bridge"] \
+ vif.attributes["network"] \
= get_child_by_name(vif_sxp, "bridge")
return vif
_eths = -1
+ def mk_other_config(self, key, value, document):
+ other_config = document.createElement("other_config")
+ other_config.attributes["key"] = key
+ other_config.attributes["value"] = value
+ return other_config
+
+ def extract_consoles(self, image, document):
+ consoles = []
+
+ if int(get_child_by_name(image, "nographic", "1")) == 1:
+ return consoles
+
+ if int(get_child_by_name(image, "vnc", "0")) == 1:
+ console = document.createElement("console")
+ console.attributes["protocol"] = "rfb"
+ console.appendChild(self.mk_other_config(
+ "vncunused", str(get_child_by_name(image, "vncunused", "0")),
+ document))
+ console.appendChild(self.mk_other_config(
+ "vnclisten",
+ get_child_by_name(image, "vnclisten", "127.0.0.1"),
+ document))
+ console.appendChild(self.mk_other_config(
+ "vncpasswd", get_child_by_name(image, "vncpasswd", ""),
+ document))
+ consoles.append(console)
+ if int(get_child_by_name(image, "sdl", "0")) == 1:
+ console = document.createElement("console")
+ console.attributes["protocol"] = "sdl"
+ console.appendChild(self.mk_other_config(
+ "display", get_child_by_name(image, "display", ""),
+ document))
+ console.appendChild(self.mk_other_config(
+ "xauthority",
+ get_child_by_name(image, "vxauthority", "127.0.0.1"),
+ document))
+ console.appendChild(self.mk_other_config(
+ "vncpasswd", get_child_by_name(image, "vncpasswd", ""),
+ document))
+ consoles.append(console)
+
+ return consoles
+
+
+ def extract_platform(self, image, document):
+ platform_keys = ['acpi', 'apic', 'pae']
+
+ def extract_platform_key(key):
+ platform = document.createElement("platform")
+ platform.attributes["key"] = key
+ platform.attributes["value"] \
+ = str(get_child_by_name(image, key, "1"))
+ return platform
+
+ return map(extract_platform_key, platform_keys)
+
def getFreshEthDevice(self):
self._eths += 1
return "eth%i" % self._eths
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/security/policies/security_policy.xsd
--- a/tools/security/policies/security_policy.xsd Fri Mar 30 10:27:15
2007 -0600
+++ b/tools/security/policies/security_policy.xsd Fri Mar 30 17:18:42
2007 -0600
@@ -22,6 +22,8 @@
<xsd:element name="Reference" type="xsd:string"
minOccurs="0" maxOccurs="1" />
<xsd:element name="Date" minOccurs="0"
maxOccurs="1" type="xsd:string"></xsd:element>
<xsd:element name="NameSpaceUrl" minOccurs="0"
maxOccurs="1" type="xsd:string"></xsd:element>
+ <xsd:element name="Version" minOccurs="0"
maxOccurs="1" type="VersionFormat"/>
+ <xsd:element ref="FromPolicy" minOccurs="0"
maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
@@ -116,4 +118,17 @@
<xsd:enumeration
value="PrimaryPolicyComponent"></xsd:enumeration>
</xsd:restriction>
</xsd:simpleType>
+ <xsd:element name="FromPolicy">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="PolicyName" minOccurs="1"
maxOccurs="1" type="xsd:string"/>
+ <xsd:element name="Version" minOccurs="1"
maxOccurs="1" type="VersionFormat"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:simpleType name="VersionFormat">
+ <xsd:restriction base="xsd:string">
+ <xsd:pattern
value="[0-9]{1,8}.[0-9]{1,8}"></xsd:pattern>
+ </xsd:restriction>
+ </xsd:simpleType>
</xsd:schema>
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/security/secpol_tool.c
--- a/tools/security/secpol_tool.c Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/security/secpol_tool.c Fri Mar 30 17:18:42 2007 -0600
@@ -57,7 +57,7 @@ void usage(char *progname)
/*************************** DUMPS *******************************/
-void acm_dump_chinesewall_buffer(void *buf, int buflen)
+void acm_dump_chinesewall_buffer(void *buf, int buflen, uint16_t chwall_ref)
{
struct acm_chwall_policy_buffer *cwbuf =
@@ -91,6 +91,8 @@ void acm_dump_chinesewall_buffer(void *b
for (j = 0; j < ntohl(cwbuf->chwall_max_types); j++)
printf("%02x ",
ntohs(ssids[i * ntohl(cwbuf->chwall_max_types) + j]));
+ if (i == chwall_ref)
+ printf(" <-- Domain-0");
}
printf("\n\nConfict Sets:\n");
conflicts =
@@ -131,7 +133,7 @@ void acm_dump_chinesewall_buffer(void *b
}
}
-void acm_dump_ste_buffer(void *buf, int buflen)
+void acm_dump_ste_buffer(void *buf, int buflen, uint16_t ste_ref)
{
struct acm_ste_policy_buffer *stebuf =
@@ -158,11 +160,14 @@ void acm_dump_ste_buffer(void *buf, int
for (j = 0; j < ntohl(stebuf->ste_max_types); j++)
printf("%02x ",
ntohs(ssids[i * ntohl(stebuf->ste_max_types) + j]));
+ if (i == ste_ref)
+ printf(" <-- Domain-0");
}
printf("\n\n");
}
-void acm_dump_policy_buffer(void *buf, int buflen)
+void acm_dump_policy_buffer(void *buf, int buflen,
+ uint16_t chwall_ref, uint16_t ste_ref)
{
struct acm_policy_buffer *pol = (struct acm_policy_buffer *) buf;
char *policy_reference_name =
@@ -172,6 +177,9 @@ void acm_dump_policy_buffer(void *buf, i
printf("============\n");
printf("POLICY REFERENCE = %s.\n", policy_reference_name);
printf("PolicyVer = %x.\n", ntohl(pol->policy_version));
+ printf("XML Vers. = %d.%d\n",
+ ntohl(pol->xml_pol_version.major),
+ ntohl(pol->xml_pol_version.minor));
printf("Magic = %x.\n", ntohl(pol->magic));
printf("Len = %x.\n", ntohl(pol->len));
printf("Primary = %s (c=%x, off=%x).\n",
@@ -187,13 +195,15 @@ void acm_dump_policy_buffer(void *buf, i
acm_dump_chinesewall_buffer(ALIGN8(buf +
ntohl(pol->primary_buffer_offset)),
ntohl(pol->len) -
- ntohl(pol->primary_buffer_offset));
+ ntohl(pol->primary_buffer_offset),
+ chwall_ref);
break;
case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
acm_dump_ste_buffer(ALIGN8(buf + ntohl(pol->primary_buffer_offset)),
ntohl(pol->len) -
- ntohl(pol->primary_buffer_offset));
+ ntohl(pol->primary_buffer_offset),
+ ste_ref);
break;
case ACM_NULL_POLICY:
@@ -209,13 +219,15 @@ void acm_dump_policy_buffer(void *buf, i
acm_dump_chinesewall_buffer(ALIGN8(buf +
ntohl(pol->secondary_buffer_offset)),
ntohl(pol->len) -
- ntohl(pol->secondary_buffer_offset));
+ ntohl(pol->secondary_buffer_offset),
+ chwall_ref);
break;
case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
acm_dump_ste_buffer(ALIGN8(buf + ntohl(pol->secondary_buffer_offset)),
ntohl(pol->len) -
- ntohl(pol->secondary_buffer_offset));
+ ntohl(pol->secondary_buffer_offset),
+ ste_ref);
break;
case ACM_NULL_POLICY:
@@ -227,6 +239,27 @@ void acm_dump_policy_buffer(void *buf, i
}
}
+/************************** get dom0 ssidref *****************************/
+int acm_get_ssidref(int xc_handle, int domid, uint16_t *chwall_ref,
+ uint16_t *ste_ref)
+{
+ int ret;
+ struct acm_getssid getssid;
+ char buf[4096];
+ struct acm_ssid_buffer *ssid = (struct acm_ssid_buffer *)buf;
+ getssid.interface_version = ACM_INTERFACE_VERSION;
+ set_xen_guest_handle(getssid.ssidbuf, buf);
+ getssid.ssidbuf_size = sizeof(buf);
+ getssid.get_ssid_by = ACM_GETBY_domainid;
+ getssid.id.domainid = domid;
+ ret = xc_acm_op(xc_handle, ACMOP_getssid, &getssid, sizeof(getssid));
+ if (ret == 0) {
+ *chwall_ref = ssid->ssidref & 0xffff;
+ *ste_ref = ssid->ssidref >> 16;
+ }
+ return ret;
+}
+
/******************************* get policy ******************************/
#define PULL_CACHE_SIZE 8192
@@ -236,12 +269,16 @@ int acm_domain_getpolicy(int xc_handle)
{
struct acm_getpolicy getpolicy;
int ret;
+ uint16_t chwall_ref, ste_ref;
memset(pull_buffer, 0x00, sizeof(pull_buffer));
getpolicy.interface_version = ACM_INTERFACE_VERSION;
set_xen_guest_handle(getpolicy.pullcache, pull_buffer);
getpolicy.pullcache_size = sizeof(pull_buffer);
ret = xc_acm_op(xc_handle, ACMOP_getpolicy, &getpolicy, sizeof(getpolicy));
+ if (ret >= 0) {
+ ret = acm_get_ssidref(xc_handle, 0, &chwall_ref, &ste_ref);
+ }
if (ret < 0) {
printf("ACM operation failed: errno=%d\n", errno);
@@ -251,7 +288,9 @@ int acm_domain_getpolicy(int xc_handle)
}
/* dump policy */
- acm_dump_policy_buffer(pull_buffer, sizeof(pull_buffer));
+ acm_dump_policy_buffer(pull_buffer, sizeof(pull_buffer),
+ chwall_ref, ste_ref);
+
return ret;
}
@@ -263,6 +302,7 @@ int acm_domain_loadpolicy(int xc_handle,
int ret, fd;
off_t len;
uint8_t *buffer;
+ uint16_t chwall_ssidref, ste_ssidref;
if ((ret = stat(filename, &mystat))) {
printf("File %s not found.\n", filename);
@@ -279,10 +319,14 @@ int acm_domain_loadpolicy(int xc_handle,
printf("File %s not found.\n", filename);
goto free_out;
}
+ ret =acm_get_ssidref(xc_handle, 0, &chwall_ssidref, &ste_ssidref);
+ if (ret < 0) {
+ goto free_out;
+ }
if (len == read(fd, buffer, len)) {
struct acm_setpolicy setpolicy;
/* dump it and then push it down into xen/acm */
- acm_dump_policy_buffer(buffer, len);
+ acm_dump_policy_buffer(buffer, len, chwall_ssidref, ste_ssidref);
setpolicy.interface_version = ACM_INTERFACE_VERSION;
set_xen_guest_handle(setpolicy.pushcache, buffer);
setpolicy.pushcache_size = len;
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/security/secpol_xml2bin.c
--- a/tools/security/secpol_xml2bin.c Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/security/secpol_xml2bin.c Fri Mar 30 17:18:42 2007 -0600
@@ -108,26 +108,25 @@ char *policy_filename = NULL,
char *policy_reference_name = NULL;
+char *policy_version_string = NULL;
+
void walk_labels(xmlNode * start, xmlDocPtr doc, unsigned long state);
void usage(char *prg)
{
- printf("Usage: %s [OPTIONS] POLICYNAME\n", prg);
- printf
- ("POLICYNAME is the directory name within the policy directory\n");
- printf
- ("that contains the policy files. The default policy directory\n");
- printf("is '%s' (see the '-d' option below to change it)\n",
- POLICY_DIR);
- printf
- ("The policy files contained in the POLICYNAME directory must be
named:\n");
- printf("\tPOLICYNAME-security_policy.xml\n");
- printf("\tPOLICYNAME-security_label_template.xml\n\n");
- printf("OPTIONS:\n");
- printf("\t-d POLICYDIR\n");
- printf
- ("\t\tUse POLICYDIR as the policy directory. This directory must
contain\n");
- printf("\t\tthe policy schema file 'security_policy.xsd'\n");
+ printf(
+ "Usage: %s [OPTIONS] POLICYNAME\n"
+ "POLICYNAME is the directory name within the policy directory\n"
+ "that contains the policy files. The default policy directory\n"
+ "is '%s' (see the '-d' option below to change it)\n"
+ "The policy files contained in the POLICYNAME directory must be named:\n"
+ "\tPOLICYNAME-security_policy.xml\n"
+ "\tPOLICYNAME-security_label_template.xml\n\n"
+ "OPTIONS:\n"
+ "\t-d POLICYDIR\n"
+ "\t\tUse POLICYDIR as the policy directory. This directory must \n"
+ "\t\tcontain the policy schema file 'security_policy.xsd'\n",
+ prg, POLICY_DIR);
exit(EXIT_FAILURE);
}
@@ -300,25 +299,50 @@ void walk_policy(xmlNode * start, xmlDoc
case XML2BIN_CHWALLTYPES:
case XML2BIN_CONFLICTSETS:
case XML2BIN_POLICYHEADER:
+ case XML2BIN_FROMPOLICY:
walk_policy(cur_node->children, doc, state | (1 << code));
break;
case XML2BIN_POLICYNAME: /* get policy reference name .... */
- if (state != XML2BIN_PN_S) {
+ if (state != XML2BIN_PN_S &&
+ state != XML2BIN_PN_frompolicy_S) {
printf("ERROR: >Url< >%s< out of context.\n",
(char *) xmlNodeListGetString(doc,
cur_node->
xmlChildrenNode, 1));
exit(EXIT_FAILURE);
}
- policy_reference_name = (char *)
- xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1);
- if (!policy_reference_name) {
- printf("ERROR: empty >policy reference name (Url)<!\n");
+ if (state == XML2BIN_PN_S) {
+ policy_reference_name = (char *)
+ xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1);
+ if (!policy_reference_name) {
+ printf("ERROR: empty >policy reference name (Url)<!\n");
+ exit(EXIT_FAILURE);
+ } else
+ printf("Policy Reference name (Url): %s\n",
+ policy_reference_name);
+ }
+ break;
+
+ case XML2BIN_VERSION: /* get policy version number .... */
+ if (state != XML2BIN_PN_S &&
+ state != XML2BIN_PN_frompolicy_S) {
+ printf("ERROR: >Url< >%s< out of context.\n",
+ (char *) xmlNodeListGetString(doc,
+ cur_node->
+ xmlChildrenNode, 1));
exit(EXIT_FAILURE);
- } else
- printf("Policy Reference name (Url): %s\n",
- policy_reference_name);
+ }
+ if (state == XML2BIN_PN_S) {
+ policy_version_string = (char *)
+ xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1);
+ if (!policy_version_string) {
+ printf("ERROR: empty >policy version string <!\n");
+ exit(EXIT_FAILURE);
+ } else
+ printf("Policy version string: %s\n",
+ policy_version_string);
+ }
break;
case XML2BIN_STE:
@@ -1135,8 +1159,12 @@ int write_binary(char *filename)
NULL, *policy_reference_buffer = NULL;
u_int32_t len;
int fd, ret = 0;
+ uint32_t major = 0, minor = 0;
u_int32_t len_ste = 0, len_chwall = 0, len_pr = 0; /* length of policy
components */
+
+ if (policy_version_string)
+ sscanf(policy_version_string,"%d.%d", &major, &minor);
/* open binary file */
if ((fd =
@@ -1152,6 +1180,8 @@ int write_binary(char *filename)
/* determine primary component (default chwall) */
header.policy_version = htonl(ACM_POLICY_VERSION);
header.magic = htonl(ACM_MAGIC);
+ header.xml_pol_version.major = htonl(major);
+ header.xml_pol_version.minor = htonl(minor);
len = sizeof(struct acm_policy_buffer);
if (have_chwall)
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/security/secpol_xml2bin.h
--- a/tools/security/secpol_xml2bin.h Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/security/secpol_xml2bin.h Fri Mar 30 17:18:42 2007 -0600
@@ -22,31 +22,35 @@
#define SCHEMA_FILENAME "security_policy.xsd"
/* basic states (used as 1 << X) */
-#define ENDOFLIST_POS 22 /* ADAPT!! this position will be NULL;
stay below 32 (bit) */
-#define XML2BIN_SECPOL 0 /* policy tokens */
-#define XML2BIN_STE 1
-#define XML2BIN_CHWALL 2
-#define XML2BIN_CONFLICTSETS 3
-#define XML2BIN_CSTYPE 4
-#define XML2BIN_POLICYHEADER 5
-#define XML2BIN_NSURL 6
-#define XML2BIN_POLICYNAME 7
-#define XML2BIN_URL 8
-#define XML2BIN_REFERENCE 9
-#define XML2BIN_DATE 10
+enum {
+ XML2BIN_SECPOL = 0, /* policy tokens */
+ XML2BIN_STE,
+ XML2BIN_CHWALL,
+ XML2BIN_CONFLICTSETS,
+ XML2BIN_CSTYPE,
+ XML2BIN_POLICYHEADER,
+ XML2BIN_NSURL,
+ XML2BIN_POLICYNAME,
+ XML2BIN_URL,
+ XML2BIN_REFERENCE,
+ XML2BIN_DATE,
+ XML2BIN_VERSION,
+ XML2BIN_FROMPOLICY,
-#define XML2BIN_LABELTEMPLATE 11 /* label tokens */
-#define XML2BIN_SUBJECTS 12
-#define XML2BIN_OBJECTS 13
-#define XML2BIN_VM 14
-#define XML2BIN_RES 15
-#define XML2BIN_NAME 16
+ XML2BIN_LABELTEMPLATE, /* label tokens */
+ XML2BIN_SUBJECTS,
+ XML2BIN_OBJECTS,
+ XML2BIN_VM,
+ XML2BIN_RES,
+ XML2BIN_NAME,
-#define XML2BIN_STETYPES 17 /* shared tokens */
-#define XML2BIN_CHWALLTYPES 18
-#define XML2BIN_TYPE 19
-#define XML2BIN_TEXT 20
-#define XML2BIN_COMMENT 21
+ XML2BIN_STETYPES,
+ XML2BIN_CHWALLTYPES,
+ XML2BIN_TYPE,
+ XML2BIN_TEXT,
+ XML2BIN_COMMENT,
+ ENDOFLIST_POS /* keep last ! */
+};
/* type "data type" (currently 16bit) */
typedef u_int16_t type_t;
@@ -68,6 +72,8 @@ char *token[32] =
[XML2BIN_URL] = "PolicyUrl",
[XML2BIN_REFERENCE] = "Reference",
[XML2BIN_DATE] = "Date",
+ [XML2BIN_VERSION] = "Version",
+ [XML2BIN_FROMPOLICY] = "FromPolicy",
[XML2BIN_LABELTEMPLATE] = "SecurityLabelTemplate", /* label-template xml */
[XML2BIN_SUBJECTS] = "SubjectLabels",
@@ -79,7 +85,7 @@ char *token[32] =
[XML2BIN_STETYPES] = "SimpleTypeEnforcementTypes", /* common tags */
[XML2BIN_CHWALLTYPES] = "ChineseWallTypes",
[XML2BIN_TYPE] = "Type",
- [XML2BIN_TEXT] = "text",
+ [XML2BIN_TEXT] = "text",
[XML2BIN_COMMENT] = "comment",
[ENDOFLIST_POS] = NULL /* End of LIST, adapt ENDOFLIST_POS
when adding entries */
@@ -112,6 +118,10 @@ char *token[32] =
#define XML2BIN_PN_S ((1 << XML2BIN_SECPOL) | \
(1 << XML2BIN_POLICYHEADER))
+#define XML2BIN_PN_frompolicy_S ((1 << XML2BIN_SECPOL) | \
+ (1 << XML2BIN_POLICYHEADER) | \
+ (1 << XML2BIN_FROMPOLICY))
+
/* label xml states */
#define XML2BIN_VM_S ((1 << XML2BIN_SECPOL) | \
(1 << XML2BIN_LABELTEMPLATE) | \
@@ -147,7 +157,7 @@ char *token[32] =
*/
/* protects from unnoticed changes in struct acm_policy_buffer */
-#define WRITTEN_AGAINST_ACM_POLICY_VERSION 2
+#define WRITTEN_AGAINST_ACM_POLICY_VERSION 3
/* protects from unnoticed changes in struct acm_chwall_policy_buffer */
#define WRITTEN_AGAINST_ACM_CHWALL_VERSION 1
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/xcutils/xc_restore.c
--- a/tools/xcutils/xc_restore.c Fri Mar 30 10:27:15 2007 -0600
+++ b/tools/xcutils/xc_restore.c Fri Mar 30 17:18:42 2007 -0600
@@ -42,8 +42,6 @@ main(int argc, char **argv)
apic = atoi(argv[8]);
if (hvm) {
- /* pass the memsize to xc_hvm_restore to find the store_mfn */
- store_mfn = hvm;
ret = xc_hvm_restore(xc_fd, io_fd, domid, max_pfn, store_evtchn,
&store_mfn, pae, apic);
} else
diff -r e7da2fcb7a22 -r fc9e2f7920c9 tools/xm-test/lib/XmTestLib/XenAPIDomain.py
--- a/tools/xm-test/lib/XmTestLib/XenAPIDomain.py Fri Mar 30 10:27:15
2007 -0600
+++ b/tools/xm-test/lib/XmTestLib/XenAPIDomain.py Fri Mar 30 17:18:42
2007 -0600
@@ -22,7 +22,6 @@ import os
import os
import sys
from XmTestLib import *
-from xen.util.xmlrpclib2 import ServerProxy
from types import DictType
diff -r e7da2fcb7a22 -r fc9e2f7920c9
tools/xm-test/tests/destroy/06_destroy_dom0_neg.py
--- a/tools/xm-test/tests/destroy/06_destroy_dom0_neg.py Fri Mar 30
10:27:15 2007 -0600
+++ b/tools/xm-test/tests/destroy/06_destroy_dom0_neg.py Fri Mar 30
17:18:42 2007 -0600
@@ -10,5 +10,5 @@ status, output = traceCommand("xm destro
status, output = traceCommand("xm destroy 0")
if status == 0:
FAIL("xm destroy returned bad status, expected non 0, status is: %i" %
status)
-elif not re.search("Error", output):
+elif not re.search("Error", output, re.I):
FAIL("xm destroy returned bad output, expected Error:, output is: %s" %
output)
diff -r e7da2fcb7a22 -r fc9e2f7920c9
unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
--- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c Fri Mar 30
10:27:15 2007 -0600
+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c Fri Mar 30
17:18:42 2007 -0600
@@ -36,6 +36,7 @@
#include <asm/pgtable.h>
#include <xen/interface/memory.h>
#include <xen/features.h>
+#include <xen/gnttab.h>
#ifdef __ia64__
#include <asm/xen/xencomm.h>
#endif
@@ -61,9 +62,11 @@ unsigned long *phys_to_machine_mapping;
unsigned long *phys_to_machine_mapping;
EXPORT_SYMBOL(phys_to_machine_mapping);
+static unsigned long shared_info_frame;
+static uint64_t callback_via;
+
static int __devinit init_xen_info(void)
{
- unsigned long shared_info_frame;
struct xen_add_to_physmap xatp;
extern void *shared_info_area;
@@ -219,7 +222,6 @@ static int __devinit platform_pci_init(s
int i, ret;
long ioaddr, iolen;
long mmio_addr, mmio_len;
- uint64_t callback_via;
i = pci_enable_device(pdev);
if (i)
@@ -303,6 +305,35 @@ static struct pci_driver platform_driver
static int pci_device_registered;
+void platform_pci_suspend(void)
+{
+ gnttab_suspend();
+}
+EXPORT_SYMBOL_GPL(platform_pci_suspend);
+
+void platform_pci_resume(void)
+{
+ struct xen_add_to_physmap xatp;
+ phys_to_machine_mapping = NULL;
+
+ /* do 2 things for PV driver restore on HVM
+ * 1: rebuild share info
+ * 2: set callback irq again
+ */
+ xatp.domid = DOMID_SELF;
+ xatp.idx = 0;
+ xatp.space = XENMAPSPACE_shared_info;
+ xatp.gpfn = shared_info_frame;
+ if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
+ BUG();
+
+ if (( set_callback_via(callback_via)))
+ printk("platform_pci_resume failure!\n");
+
+ gnttab_resume();
+}
+EXPORT_SYMBOL_GPL(platform_pci_resume);
+
static int __init platform_pci_module_init(void)
{
int rc;
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/acm/acm_chinesewall_hooks.c
--- a/xen/acm/acm_chinesewall_hooks.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/acm/acm_chinesewall_hooks.c Fri Mar 30 17:18:42 2007 -0600
@@ -41,6 +41,9 @@
#include <acm/acm_core.h>
#include <acm/acm_hooks.h>
#include <acm/acm_endian.h>
+#include <acm/acm_core.h>
+
+ssidref_t dom0_chwall_ssidref = 0x0001;
/* local cache structures for chinese wall policy */
struct chwall_binary_policy chwall_bin_pol;
@@ -53,7 +56,7 @@ int acm_init_chwall_policy(void)
{
/* minimal startup policy; policy write-locked already */
chwall_bin_pol.max_types = 1;
- chwall_bin_pol.max_ssidrefs = 2;
+ chwall_bin_pol.max_ssidrefs = 1 + dom0_chwall_ssidref;
chwall_bin_pol.max_conflictsets = 1;
chwall_bin_pol.ssidrefs =
(domaintype_t *) xmalloc_array(domaintype_t,
@@ -254,7 +257,7 @@ chwall_init_state(struct acm_chwall_poli
* more than one type is currently running */
}
-static int chwall_set_policy(u8 * buf, u32 buf_size)
+static int chwall_set_policy(u8 * buf, u32 buf_size, int is_bootpolicy)
{
/* policy write-locked already */
struct acm_chwall_policy_buffer *chwall_buf =
@@ -285,6 +288,12 @@ static int chwall_set_policy(u8 * buf, u
if ((chwall_buf->policy_code != ACM_CHINESE_WALL_POLICY) ||
(chwall_buf->policy_version != ACM_CHWALL_VERSION))
return -EINVAL;
+
+ /* during boot dom0_chwall_ssidref is set */
+ if (is_bootpolicy &&
+ (dom0_chwall_ssidref >= chwall_buf->chwall_max_ssidrefs)) {
+ goto error_free;
+ }
/* 1. allocate new buffers */
ssids =
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/acm/acm_core.c
--- a/xen/acm/acm_core.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/acm/acm_core.c Fri Mar 30 17:18:42 2007 -0600
@@ -62,18 +62,63 @@ struct acm_binary_policy acm_bin_pol;
/* acm binary policy lock */
DEFINE_RWLOCK(acm_bin_pol_rwlock);
+/* ACM's only accepted policy name */
+char polname[80];
+char *acm_accepted_boot_policy_name = NULL;
+
+static void __init set_dom0_ssidref(const char *val)
+{
+ /* expected format:
+ ssidref=<hex number>:<policy name>
+ Policy name must not have a 'space'.
+ */
+ const char *c;
+ int lo, hi;
+ int i;
+ int dom0_ssidref = simple_strtoull(val, &c, 0);
+
+ if (!strncmp(&c[0],":sHype:", 7)) {
+ lo = dom0_ssidref & 0xffff;
+ if (lo < ACM_MAX_NUM_TYPES && lo >= 1)
+ dom0_chwall_ssidref = lo;
+ hi = dom0_ssidref >> 16;
+ if (hi < ACM_MAX_NUM_TYPES && hi >= 1)
+ dom0_ste_ssidref = hi;
+ for (i = 0; i < sizeof(polname); i++) {
+ polname[i] = c[7+i];
+ if (polname[i] == '\0' || polname[i] == '\t' ||
+ polname[i] == '\n' || polname[i] == ' ' ||
+ polname[i] == ':') {
+ break;
+ }
+ }
+ polname[i] = 0;
+ acm_accepted_boot_policy_name = polname;
+ }
+}
+
+custom_param("ssidref", set_dom0_ssidref);
+
int
acm_set_policy_reference(u8 *buf, u32 buf_size)
{
+ char *name = (char *)(buf + sizeof(struct acm_policy_reference_buffer));
struct acm_policy_reference_buffer *pr = (struct
acm_policy_reference_buffer *)buf;
+
+ if (acm_accepted_boot_policy_name != NULL) {
+ if (strcmp(acm_accepted_boot_policy_name, name)) {
+ printk("Policy's name '%s' is not the expected one '%s'.\n",
+ name, acm_accepted_boot_policy_name);
+ return ACM_ERROR;
+ }
+ }
+
acm_bin_pol.policy_reference_name = (char *)xmalloc_array(u8,
be32_to_cpu(pr->len));
if (!acm_bin_pol.policy_reference_name)
return -ENOMEM;
-
- strlcpy(acm_bin_pol.policy_reference_name,
- (char *)(buf + sizeof(struct acm_policy_reference_buffer)),
- be32_to_cpu(pr->len));
+ strlcpy(acm_bin_pol.policy_reference_name, name, be32_to_cpu(pr->len));
+
printk("%s: Activating policy %s\n", __func__,
acm_bin_pol.policy_reference_name);
return 0;
@@ -190,7 +235,8 @@ acm_is_policy(char *buf, unsigned long l
static int
acm_setup(char *policy_start,
- unsigned long policy_len)
+ unsigned long policy_len,
+ int is_bootpolicy)
{
int rc = ACM_OK;
struct acm_policy_buffer *pol;
@@ -202,7 +248,8 @@ acm_setup(char *policy_start,
if (be32_to_cpu(pol->magic) != ACM_MAGIC)
return rc;
- rc = do_acm_set_policy((void *)policy_start, (u32)policy_len);
+ rc = do_acm_set_policy((void *)policy_start, (u32)policy_len,
+ is_bootpolicy);
if (rc == ACM_OK)
{
printkd("Policy len 0x%lx, start at %p.\n",policy_len,policy_start);
@@ -224,7 +271,10 @@ acm_init(char *policy_start,
int ret = ACM_OK;
/* first try to load the boot policy (uses its own locks) */
- acm_setup(policy_start, policy_len);
+ acm_setup(policy_start, policy_len, 1);
+
+ /* a user-provided policy may have any name; only matched during boot */
+ acm_accepted_boot_policy_name = NULL;
if (acm_active_security_policy != ACM_POLICY_UNDEFINED)
{
@@ -235,6 +285,9 @@ acm_init(char *policy_start,
/* else continue with the minimal hardcoded default startup policy */
printk("%s: Loading default policy (%s).\n",
__func__, ACM_POLICY_NAME(ACM_DEFAULT_SECURITY_POLICY));
+
+ /* (re-)set dom-0 ssidref to default */
+ dom0_ste_ssidref = dom0_chwall_ssidref = 0x0001;
if (acm_init_binary_policy(ACM_DEFAULT_SECURITY_POLICY)) {
ret = -EINVAL;
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/acm/acm_null_hooks.c
--- a/xen/acm/acm_null_hooks.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/acm/acm_null_hooks.c Fri Mar 30 17:18:42 2007 -0600
@@ -33,7 +33,7 @@ null_dump_binary_policy(u8 *buf, u32 buf
}
static int
-null_set_binary_policy(u8 *buf, u32 buf_size)
+null_set_binary_policy(u8 *buf, u32 buf_size, int is_bootpolicy)
{
return ACM_OK;
}
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/acm/acm_policy.c
--- a/xen/acm/acm_policy.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/acm/acm_policy.c Fri Mar 30 17:18:42 2007 -0600
@@ -50,7 +50,7 @@ acm_set_policy(XEN_GUEST_HANDLE(void) bu
printk("%s: Error copying!\n",__func__);
goto error_free;
}
- ret = do_acm_set_policy(policy_buffer, buf_size);
+ ret = do_acm_set_policy(policy_buffer, buf_size, 0);
error_free:
xfree(policy_buffer);
@@ -59,9 +59,10 @@ acm_set_policy(XEN_GUEST_HANDLE(void) bu
int
-do_acm_set_policy(void *buf, u32 buf_size)
+do_acm_set_policy(void *buf, u32 buf_size, int is_bootpolicy)
{
struct acm_policy_buffer *pol = (struct acm_policy_buffer *)buf;
+ uint32_t offset, length;
/* some sanity checking */
if ((be32_to_cpu(pol->magic) != ACM_MAGIC) ||
(buf_size != be32_to_cpu(pol->len)) ||
@@ -92,23 +93,34 @@ do_acm_set_policy(void *buf, u32 buf_siz
/* get bin_policy lock and rewrite policy (release old one) */
write_lock(&acm_bin_pol_rwlock);
+ offset = be32_to_cpu(pol->policy_reference_offset);
+ length = be32_to_cpu(pol->primary_buffer_offset) - offset;
+
/* set label reference name */
- if (acm_set_policy_reference(buf +
be32_to_cpu(pol->policy_reference_offset),
- be32_to_cpu(pol->primary_buffer_offset) -
- be32_to_cpu(pol->policy_reference_offset)))
+ if ( (offset + length) > buf_size ||
+ acm_set_policy_reference(buf + offset, length))
goto error_lock_free;
/* set primary policy data */
- if (acm_primary_ops->set_binary_policy(buf +
be32_to_cpu(pol->primary_buffer_offset),
-
be32_to_cpu(pol->secondary_buffer_offset) -
-
be32_to_cpu(pol->primary_buffer_offset)))
+ offset = be32_to_cpu(pol->primary_buffer_offset);
+ length = be32_to_cpu(pol->secondary_buffer_offset) - offset;
+
+ if ( (offset + length) > buf_size ||
+ acm_primary_ops->set_binary_policy(buf + offset, length,
+ is_bootpolicy))
goto error_lock_free;
/* set secondary policy data */
- if (acm_secondary_ops->set_binary_policy(buf +
be32_to_cpu(pol->secondary_buffer_offset),
- be32_to_cpu(pol->len) -
-
be32_to_cpu(pol->secondary_buffer_offset)))
- goto error_lock_free;
+ offset = be32_to_cpu(pol->secondary_buffer_offset);
+ length = be32_to_cpu(pol->len) - offset;
+ if ( (offset + length) > buf_size ||
+ acm_secondary_ops->set_binary_policy(buf + offset, length,
+ is_bootpolicy))
+ goto error_lock_free;
+
+ memcpy(&acm_bin_pol.xml_pol_version,
+ &pol->xml_pol_version,
+ sizeof(acm_bin_pol.xml_pol_version));
write_unlock(&acm_bin_pol_rwlock);
return ACM_OK;
@@ -126,7 +138,7 @@ acm_get_policy(XEN_GUEST_HANDLE(void) bu
u8 *policy_buffer;
int ret;
struct acm_policy_buffer *bin_pol;
-
+
if (buf_size < sizeof(struct acm_policy_buffer))
return -EFAULT;
@@ -145,6 +157,10 @@ acm_get_policy(XEN_GUEST_HANDLE(void) bu
bin_pol->primary_buffer_offset = cpu_to_be32(be32_to_cpu(bin_pol->len));
bin_pol->secondary_buffer_offset = cpu_to_be32(be32_to_cpu(bin_pol->len));
+ memcpy(&bin_pol->xml_pol_version,
+ &acm_bin_pol.xml_pol_version,
+ sizeof(struct acm_policy_version));
+
ret = acm_dump_policy_reference(policy_buffer +
be32_to_cpu(bin_pol->policy_reference_offset),
buf_size -
be32_to_cpu(bin_pol->policy_reference_offset));
if (ret < 0)
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/acm/acm_simple_type_enforcement_hooks.c
--- a/xen/acm/acm_simple_type_enforcement_hooks.c Fri Mar 30 10:27:15
2007 -0600
+++ b/xen/acm/acm_simple_type_enforcement_hooks.c Fri Mar 30 17:18:42
2007 -0600
@@ -31,6 +31,9 @@
#include <acm/acm_hooks.h>
#include <asm/atomic.h>
#include <acm/acm_endian.h>
+#include <acm/acm_core.h>
+
+ssidref_t dom0_ste_ssidref = 0x0001;
/* local cache structures for STE policy */
struct ste_binary_policy ste_bin_pol;
@@ -74,15 +77,21 @@ int acm_init_ste_policy(void)
{
/* minimal startup policy; policy write-locked already */
ste_bin_pol.max_types = 1;
- ste_bin_pol.max_ssidrefs = 2;
- ste_bin_pol.ssidrefs = (domaintype_t *)xmalloc_array(domaintype_t, 2);
- memset(ste_bin_pol.ssidrefs, 0, 2);
+ ste_bin_pol.max_ssidrefs = 1 + dom0_ste_ssidref;
+ ste_bin_pol.ssidrefs =
+ (domaintype_t *)xmalloc_array(domaintype_t,
+ ste_bin_pol.max_types *
+ ste_bin_pol.max_ssidrefs);
if (ste_bin_pol.ssidrefs == NULL)
return ACM_INIT_SSID_ERROR;
- /* initialize state so that dom0 can start up and communicate with itself */
- ste_bin_pol.ssidrefs[1] = 1;
+ memset(ste_bin_pol.ssidrefs, 0, sizeof(domaintype_t) *
+ ste_bin_pol.max_types *
+ ste_bin_pol.max_ssidrefs);
+
+ /* initialize state so that dom0 can start up and communicate with itself
*/
+ ste_bin_pol.ssidrefs[ste_bin_pol.max_types * dom0_ste_ssidref] = 1;
/* init stats */
atomic_set(&(ste_bin_pol.ec_eval_count), 0);
@@ -274,7 +283,7 @@ ste_init_state(struct acm_ste_policy_buf
/* set new policy; policy write-locked already */
static int
-ste_set_policy(u8 *buf, u32 buf_size)
+ste_set_policy(u8 *buf, u32 buf_size, int is_bootpolicy)
{
struct acm_ste_policy_buffer *ste_buf = (struct acm_ste_policy_buffer
*)buf;
void *ssidrefsbuf;
@@ -304,6 +313,11 @@ ste_set_policy(u8 *buf, u32 buf_size)
}
if (ste_buf->ste_ssid_offset + sizeof(domaintype_t) *
ste_buf->ste_max_ssidrefs*ste_buf->ste_max_types > buf_size)
goto error_free;
+
+ /* during boot dom0_chwall_ssidref is set */
+ if (is_bootpolicy && (dom0_ste_ssidref >= ste_buf->ste_max_ssidrefs)) {
+ goto error_free;
+ }
arrcpy(ssidrefsbuf,
buf + ste_buf->ste_ssid_offset,
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/asm-offsets.c
--- a/xen/arch/ia64/asm-offsets.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/asm-offsets.c Fri Mar 30 17:18:42 2007 -0600
@@ -223,10 +223,11 @@ void foo(void)
#ifdef PERF_COUNTERS
BLANK();
- DEFINE(RECOVER_TO_PAGE_FAULT_PERFC_OFS, offsetof (struct perfcounter,
recover_to_page_fault));
- DEFINE(RECOVER_TO_BREAK_FAULT_PERFC_OFS, offsetof (struct perfcounter,
recover_to_break_fault));
- DEFINE(FAST_HYPERPRIVOP_PERFC_OFS, offsetof (struct perfcounter,
fast_hyperprivop));
- DEFINE(FAST_REFLECT_PERFC_OFS, offsetof (struct perfcounter,
fast_reflect));
+ DEFINE(IA64_PERFC_recover_to_page_fault, PERFC_recover_to_page_fault);
+ DEFINE(IA64_PERFC_recover_to_break_fault, PERFC_recover_to_break_fault);
+ DEFINE(IA64_PERFC_fast_vhpt_translate, PERFC_fast_vhpt_translate);
+ DEFINE(IA64_PERFC_fast_hyperprivop, PERFC_fast_hyperprivop);
+ DEFINE(IA64_PERFC_fast_reflect, PERFC_fast_reflect);
#endif
BLANK();
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/linux-xen/irq_ia64.c
--- a/xen/arch/ia64/linux-xen/irq_ia64.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/linux-xen/irq_ia64.c Fri Mar 30 17:18:42 2007 -0600
@@ -113,7 +113,7 @@ ia64_handle_irq (ia64_vector vector, str
unsigned long saved_tpr;
#ifdef XEN
- perfc_incrc(irqs);
+ perfc_incr(irqs);
#endif
#if IRQ_DEBUG
#ifdef XEN
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/linux-xen/mca.c
--- a/xen/arch/ia64/linux-xen/mca.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/linux-xen/mca.c Fri Mar 30 17:18:42 2007 -0600
@@ -396,16 +396,6 @@ ia64_log_queue(int sal_info_type, int vi
#ifdef CONFIG_ACPI
#ifdef XEN
-/**
- * Copy from linux/include/asm-generic/bug.h
- */
-#define WARN_ON(condition) do { \
- if (unlikely((condition)!=0)) { \
- printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__,
__LINE__); \
- dump_stack(); \
- } \
-} while (0)
-
/**
* Copy from linux/kernel/irq/manage.c
*
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/linux-xen/smp.c
--- a/xen/arch/ia64/linux-xen/smp.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/linux-xen/smp.c Fri Mar 30 17:18:42 2007 -0600
@@ -148,7 +148,7 @@ handle_IPI (int irq, void *dev_id, struc
unsigned long ops;
#ifdef XEN
- perfc_incrc(ipis);
+ perfc_incr(ipis);
#endif
mb(); /* Order interrupt and bit testing. */
while ((ops = xchg(pending_ipis, 0)) != 0) {
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/vmx/pal_emul.c
--- a/xen/arch/ia64/vmx/pal_emul.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/vmx/pal_emul.c Fri Mar 30 17:18:42 2007 -0600
@@ -37,7 +37,7 @@ pal_emul(struct vcpu *vcpu)
vcpu_get_gr_nat(vcpu, 30, &gr30);
vcpu_get_gr_nat(vcpu, 31, &gr31);
- perfc_incrc(vmx_pal_emul);
+ perfc_incr(vmx_pal_emul);
result = xen_pal_emulator(gr28, gr29, gr30, gr31);
vcpu_set_gr(vcpu, 8, result.status, 0);
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/vmx/vlsapic.c
--- a/xen/arch/ia64/vmx/vlsapic.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/vmx/vlsapic.c Fri Mar 30 17:18:42 2007 -0600
@@ -692,8 +692,8 @@ static void vlsapic_write_ipi(VCPU *vcpu
if (targ == NULL)
panic_domain(NULL, "Unknown IPI cpu\n");
- if (!test_bit(_VCPUF_initialised, &targ->vcpu_flags) ||
- test_bit(_VCPUF_down, &targ->vcpu_flags)) {
+ if (!targ->is_initialised ||
+ test_bit(_VPF_down, &targ->pause_flags)) {
struct pt_regs *targ_regs = vcpu_regs(targ);
struct vcpu_guest_context c;
@@ -709,7 +709,7 @@ static void vlsapic_write_ipi(VCPU *vcpu
targ_regs->cr_iip = d->arch.sal_data->boot_rdv_ip;
targ_regs->r1 = d->arch.sal_data->boot_rdv_r1;
- if (test_and_clear_bit(_VCPUF_down,&targ->vcpu_flags)) {
+ if (test_and_clear_bit(_VPF_down,&targ->pause_flags)) {
vcpu_wake(targ);
printk(XENLOG_DEBUG "arch_boot_vcpu: vcpu %d awaken %016lx!\n",
targ->vcpu_id, targ_regs->cr_iip);
@@ -717,7 +717,7 @@ static void vlsapic_write_ipi(VCPU *vcpu
printk("arch_boot_vcpu: huh, already awake!");
}
} else {
- int running = test_bit(_VCPUF_running, &targ->vcpu_flags);
+ int running = targ->is_running;
vlsapic_deliver_ipi(targ, ((ipi_d_t)value).dm,
((ipi_d_t)value).vector);
vcpu_unblock(targ);
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/vmx/vmmu.c
--- a/xen/arch/ia64/vmx/vmmu.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/vmx/vmmu.c Fri Mar 30 17:18:42 2007 -0600
@@ -598,7 +598,7 @@ IA64FAULT vmx_vcpu_ptc_ga(VCPU *vcpu, u6
vcpu_get_rr(vcpu, va, &args.rid);
args.ps = ps;
for_each_vcpu (d, v) {
- if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
+ if (!v->is_initialised)
continue;
args.vcpu = v;
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/vmx/vmx_process.c
--- a/xen/arch/ia64/vmx/vmx_process.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/vmx/vmx_process.c Fri Mar 30 17:18:42 2007 -0600
@@ -151,7 +151,7 @@ vmx_ia64_handle_break (unsigned long ifa
struct domain *d = current->domain;
struct vcpu *v = current;
- perfc_incrc(vmx_ia64_handle_break);
+ perfc_incr(vmx_ia64_handle_break);
#ifdef CRASH_DEBUG
if ((iim == 0 || iim == CDB_BREAK_NUM) && !user_mode(regs) &&
IS_VMM_ADDRESS(regs->cr_iip)) {
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/vmx/vmx_support.c
--- a/xen/arch/ia64/vmx/vmx_support.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/vmx/vmx_support.c Fri Mar 30 17:18:42 2007 -0600
@@ -82,12 +82,12 @@ void vmx_send_assist_req(struct vcpu *v)
p->state != STATE_IOREQ_INPROCESS)
break;
- set_bit(_VCPUF_blocked_in_xen, ¤t->vcpu_flags);
+ set_bit(_VPF_blocked_in_xen, ¤t->pause_flags);
mb(); /* set blocked status /then/ re-evaluate condition */
if (p->state != STATE_IOREQ_READY &&
p->state != STATE_IOREQ_INPROCESS)
{
- clear_bit(_VCPUF_blocked_in_xen, ¤t->vcpu_flags);
+ clear_bit(_VPF_blocked_in_xen, ¤t->pause_flags);
break;
}
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/vmx/vmx_virt.c
--- a/xen/arch/ia64/vmx/vmx_virt.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/vmx/vmx_virt.c Fri Mar 30 17:18:42 2007 -0600
@@ -1401,159 +1401,159 @@ if ( (cause == 0xff && opcode == 0x1e000
switch(cause) {
case EVENT_RSM:
- perfc_incrc(vmx_rsm);
+ perfc_incr(vmx_rsm);
status=vmx_emul_rsm(vcpu, inst);
break;
case EVENT_SSM:
- perfc_incrc(vmx_ssm);
+ perfc_incr(vmx_ssm);
status=vmx_emul_ssm(vcpu, inst);
break;
case EVENT_MOV_TO_PSR:
- perfc_incrc(vmx_mov_to_psr);
+ perfc_incr(vmx_mov_to_psr);
status=vmx_emul_mov_to_psr(vcpu, inst);
break;
case EVENT_MOV_FROM_PSR:
- perfc_incrc(vmx_mov_from_psr);
+ perfc_incr(vmx_mov_from_psr);
status=vmx_emul_mov_from_psr(vcpu, inst);
break;
case EVENT_MOV_FROM_CR:
- perfc_incrc(vmx_mov_from_cr);
+ perfc_incr(vmx_mov_from_cr);
status=vmx_emul_mov_from_cr(vcpu, inst);
break;
case EVENT_MOV_TO_CR:
- perfc_incrc(vmx_mov_to_cr);
+ perfc_incr(vmx_mov_to_cr);
status=vmx_emul_mov_to_cr(vcpu, inst);
break;
case EVENT_BSW_0:
- perfc_incrc(vmx_bsw0);
+ perfc_incr(vmx_bsw0);
status=vmx_emul_bsw0(vcpu, inst);
break;
case EVENT_BSW_1:
- perfc_incrc(vmx_bsw1);
+ perfc_incr(vmx_bsw1);
status=vmx_emul_bsw1(vcpu, inst);
break;
case EVENT_COVER:
- perfc_incrc(vmx_cover);
+ perfc_incr(vmx_cover);
status=vmx_emul_cover(vcpu, inst);
break;
case EVENT_RFI:
- perfc_incrc(vmx_rfi);
+ perfc_incr(vmx_rfi);
status=vmx_emul_rfi(vcpu, inst);
break;
case EVENT_ITR_D:
- perfc_incrc(vmx_itr_d);
+ perfc_incr(vmx_itr_d);
status=vmx_emul_itr_d(vcpu, inst);
break;
case EVENT_ITR_I:
- perfc_incrc(vmx_itr_i);
+ perfc_incr(vmx_itr_i);
status=vmx_emul_itr_i(vcpu, inst);
break;
case EVENT_PTR_D:
- perfc_incrc(vmx_ptr_d);
+ perfc_incr(vmx_ptr_d);
status=vmx_emul_ptr_d(vcpu, inst);
break;
case EVENT_PTR_I:
- perfc_incrc(vmx_ptr_i);
+ perfc_incr(vmx_ptr_i);
status=vmx_emul_ptr_i(vcpu, inst);
break;
case EVENT_ITC_D:
- perfc_incrc(vmx_itc_d);
+ perfc_incr(vmx_itc_d);
status=vmx_emul_itc_d(vcpu, inst);
break;
case EVENT_ITC_I:
- perfc_incrc(vmx_itc_i);
+ perfc_incr(vmx_itc_i);
status=vmx_emul_itc_i(vcpu, inst);
break;
case EVENT_PTC_L:
- perfc_incrc(vmx_ptc_l);
+ perfc_incr(vmx_ptc_l);
status=vmx_emul_ptc_l(vcpu, inst);
break;
case EVENT_PTC_G:
- perfc_incrc(vmx_ptc_g);
+ perfc_incr(vmx_ptc_g);
status=vmx_emul_ptc_g(vcpu, inst);
break;
case EVENT_PTC_GA:
- perfc_incrc(vmx_ptc_ga);
+ perfc_incr(vmx_ptc_ga);
status=vmx_emul_ptc_ga(vcpu, inst);
break;
case EVENT_PTC_E:
- perfc_incrc(vmx_ptc_e);
+ perfc_incr(vmx_ptc_e);
status=vmx_emul_ptc_e(vcpu, inst);
break;
case EVENT_MOV_TO_RR:
- perfc_incrc(vmx_mov_to_rr);
+ perfc_incr(vmx_mov_to_rr);
status=vmx_emul_mov_to_rr(vcpu, inst);
break;
case EVENT_MOV_FROM_RR:
- perfc_incrc(vmx_mov_from_rr);
+ perfc_incr(vmx_mov_from_rr);
status=vmx_emul_mov_from_rr(vcpu, inst);
break;
case EVENT_THASH:
- perfc_incrc(vmx_thash);
+ perfc_incr(vmx_thash);
status=vmx_emul_thash(vcpu, inst);
break;
case EVENT_TTAG:
- perfc_incrc(vmx_ttag);
+ perfc_incr(vmx_ttag);
status=vmx_emul_ttag(vcpu, inst);
break;
case EVENT_TPA:
- perfc_incrc(vmx_tpa);
+ perfc_incr(vmx_tpa);
status=vmx_emul_tpa(vcpu, inst);
break;
case EVENT_TAK:
- perfc_incrc(vmx_tak);
+ perfc_incr(vmx_tak);
status=vmx_emul_tak(vcpu, inst);
break;
case EVENT_MOV_TO_AR_IMM:
- perfc_incrc(vmx_mov_to_ar_imm);
+ perfc_incr(vmx_mov_to_ar_imm);
status=vmx_emul_mov_to_ar_imm(vcpu, inst);
break;
case EVENT_MOV_TO_AR:
- perfc_incrc(vmx_mov_to_ar_reg);
+ perfc_incr(vmx_mov_to_ar_reg);
status=vmx_emul_mov_to_ar_reg(vcpu, inst);
break;
case EVENT_MOV_FROM_AR:
- perfc_incrc(vmx_mov_from_ar_reg);
+ perfc_incr(vmx_mov_from_ar_reg);
status=vmx_emul_mov_from_ar_reg(vcpu, inst);
break;
case EVENT_MOV_TO_DBR:
- perfc_incrc(vmx_mov_to_dbr);
+ perfc_incr(vmx_mov_to_dbr);
status=vmx_emul_mov_to_dbr(vcpu, inst);
break;
case EVENT_MOV_TO_IBR:
- perfc_incrc(vmx_mov_to_ibr);
+ perfc_incr(vmx_mov_to_ibr);
status=vmx_emul_mov_to_ibr(vcpu, inst);
break;
case EVENT_MOV_TO_PMC:
- perfc_incrc(vmx_mov_to_pmc);
+ perfc_incr(vmx_mov_to_pmc);
status=vmx_emul_mov_to_pmc(vcpu, inst);
break;
case EVENT_MOV_TO_PMD:
- perfc_incrc(vmx_mov_to_pmd);
+ perfc_incr(vmx_mov_to_pmd);
status=vmx_emul_mov_to_pmd(vcpu, inst);
break;
case EVENT_MOV_TO_PKR:
- perfc_incrc(vmx_mov_to_pkr);
+ perfc_incr(vmx_mov_to_pkr);
status=vmx_emul_mov_to_pkr(vcpu, inst);
break;
case EVENT_MOV_FROM_DBR:
- perfc_incrc(vmx_mov_from_dbr);
+ perfc_incr(vmx_mov_from_dbr);
status=vmx_emul_mov_from_dbr(vcpu, inst);
break;
case EVENT_MOV_FROM_IBR:
- perfc_incrc(vmx_mov_from_ibr);
+ perfc_incr(vmx_mov_from_ibr);
status=vmx_emul_mov_from_ibr(vcpu, inst);
break;
case EVENT_MOV_FROM_PMC:
- perfc_incrc(vmx_mov_from_pmc);
+ perfc_incr(vmx_mov_from_pmc);
status=vmx_emul_mov_from_pmc(vcpu, inst);
break;
case EVENT_MOV_FROM_PKR:
- perfc_incrc(vmx_mov_from_pkr);
+ perfc_incr(vmx_mov_from_pkr);
status=vmx_emul_mov_from_pkr(vcpu, inst);
break;
case EVENT_MOV_FROM_CPUID:
- perfc_incrc(vmx_mov_from_cpuid);
+ perfc_incr(vmx_mov_from_cpuid);
status=vmx_emul_mov_from_cpuid(vcpu, inst);
break;
case EVENT_VMSW:
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/xen/dom0_ops.c
--- a/xen/arch/ia64/xen/dom0_ops.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/xen/dom0_ops.c Fri Mar 30 17:18:42 2007 -0600
@@ -372,7 +372,7 @@ do_dom0vp_op(unsigned long cmd,
} else {
ret = (ret & _PFN_MASK) >> PAGE_SHIFT;//XXX pte_pfn()
}
- perfc_incrc(dom0vp_phystomach);
+ perfc_incr(dom0vp_phystomach);
break;
case IA64_DOM0VP_machtophys:
if (!mfn_valid(arg0)) {
@@ -380,7 +380,7 @@ do_dom0vp_op(unsigned long cmd,
break;
}
ret = get_gpfn_from_mfn(arg0);
- perfc_incrc(dom0vp_machtophys);
+ perfc_incr(dom0vp_machtophys);
break;
case IA64_DOM0VP_zap_physmap:
ret = dom0vp_zap_physmap(d, arg0, (unsigned int)arg1);
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/xen/domain.c Fri Mar 30 17:18:42 2007 -0600
@@ -131,11 +131,11 @@ static void flush_vtlb_for_context_switc
if (vhpt_is_flushed || NEED_FLUSH(__get_cpu_var(tlbflush_time),
last_tlbflush_timestamp)) {
local_flush_tlb_all();
- perfc_incrc(tlbflush_clock_cswitch_purge);
+ perfc_incr(tlbflush_clock_cswitch_purge);
} else {
- perfc_incrc(tlbflush_clock_cswitch_skip);
- }
- perfc_incrc(flush_vtlb_for_context_switch);
+ perfc_incr(tlbflush_clock_cswitch_skip);
+ }
+ perfc_incr(flush_vtlb_for_context_switch);
}
}
@@ -658,7 +658,7 @@ int arch_set_info_guest(struct vcpu *v,
v->arch.iva = er->iva;
}
- if (test_bit(_VCPUF_initialised, &v->vcpu_flags))
+ if (v->is_initialised)
return 0;
if (d->arch.is_vti) {
@@ -677,10 +677,12 @@ int arch_set_info_guest(struct vcpu *v,
/* This overrides some registers. */
vcpu_init_regs(v);
- /* Don't redo final setup. Auto-online VCPU0. */
- if (!test_and_set_bit(_VCPUF_initialised, &v->vcpu_flags) &&
- (v->vcpu_id == 0))
- clear_bit(_VCPUF_down, &v->vcpu_flags);
+ if (!v->is_initialised) {
+ v->is_initialised = 1;
+ /* Auto-online VCPU0 when it is initialised. */
+ if (v->vcpu_id == 0)
+ clear_bit(_VPF_down, &v->pause_flags);
+ }
return 0;
}
@@ -1068,7 +1070,7 @@ int construct_dom0(struct domain *d,
/* Sanity! */
BUG_ON(d != dom0);
BUG_ON(d->vcpu[0] == NULL);
- BUG_ON(test_bit(_VCPUF_initialised, &v->vcpu_flags));
+ BUG_ON(v->is_initialised);
printk("*** LOADING DOMAIN 0 ***\n");
@@ -1189,8 +1191,8 @@ int construct_dom0(struct domain *d,
printk("Dom0: 0x%lx\n", (u64)dom0);
- set_bit(_VCPUF_initialised, &v->vcpu_flags);
- clear_bit(_VCPUF_down, &v->vcpu_flags);
+ v->is_initialised = 1;
+ clear_bit(_VPF_down, &v->pause_flags);
/* Build firmware.
Note: Linux kernel reserve memory used by start_info, so there is
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/xen/faults.c
--- a/xen/arch/ia64/xen/faults.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/xen/faults.c Fri Mar 30 17:18:42 2007 -0600
@@ -187,7 +187,7 @@ static int handle_lazy_cover(struct vcpu
if (!PSCB(v, interrupt_collection_enabled)) {
PSCB(v, ifs) = regs->cr_ifs;
regs->cr_ifs = 0;
- perfc_incrc(lazy_cover);
+ perfc_incr(lazy_cover);
return 1; // retry same instruction with cr.ifs off
}
return 0;
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/xen/fw_emul.c
--- a/xen/arch/ia64/xen/fw_emul.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/xen/fw_emul.c Fri Mar 30 17:18:42 2007 -0600
@@ -374,7 +374,7 @@ sal_emulator (long index, unsigned long
printk("*** CALLED SAL_UPDATE_PAL. IGNORED...\n");
break;
case SAL_XEN_SAL_RETURN:
- if (!test_and_set_bit(_VCPUF_down, ¤t->vcpu_flags))
+ if (!test_and_set_bit(_VPF_down, ¤t->pause_flags))
vcpu_sleep_nosync(current);
break;
case SN_SAL_GET_MASTER_NASID:
@@ -725,7 +725,7 @@ xen_pal_emulator(unsigned long index, u6
console_start_sync();
(*efi.reset_system)(EFI_RESET_SHUTDOWN,0,0,NULL);
} else {
- set_bit(_VCPUF_down, ¤t->vcpu_flags);
+ set_bit(_VPF_down, ¤t->pause_flags);
vcpu_sleep_nosync(current);
status = PAL_STATUS_SUCCESS;
}
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/xen/hypercall.c
--- a/xen/arch/ia64/xen/hypercall.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/xen/hypercall.c Fri Mar 30 17:18:42 2007 -0600
@@ -81,11 +81,11 @@ fw_hypercall_ipi (struct pt_regs *regs)
return;
if (vector == XEN_SAL_BOOT_RENDEZ_VEC
- && (!test_bit(_VCPUF_initialised, &targ->vcpu_flags)
- || test_bit(_VCPUF_down, &targ->vcpu_flags))) {
+ && (!targ->is_initialised
+ || test_bit(_VPF_down, &targ->pause_flags))) {
/* First start: initialize vpcu. */
- if (!test_bit(_VCPUF_initialised, &targ->vcpu_flags)) {
+ if (!targ->is_initialised) {
struct vcpu_guest_context c;
memset (&c, 0, sizeof (c));
@@ -102,8 +102,8 @@ fw_hypercall_ipi (struct pt_regs *regs)
vcpu_regs (targ)->r1 = d->arch.sal_data->boot_rdv_r1;
vcpu_regs (targ)->b0 = FW_HYPERCALL_SAL_RETURN_PADDR;
- if (test_and_clear_bit(_VCPUF_down,
- &targ->vcpu_flags)) {
+ if (test_and_clear_bit(_VPF_down,
+ &targ->pause_flags)) {
vcpu_wake(targ);
printk(XENLOG_INFO "arch_boot_vcpu: vcpu %d awaken\n",
targ->vcpu_id);
@@ -112,9 +112,7 @@ fw_hypercall_ipi (struct pt_regs *regs)
printk ("arch_boot_vcpu: huu, already awaken!\n");
}
else {
- int running = test_bit(_VCPUF_running,
- &targ->vcpu_flags);
-
+ int running = targ->is_running;
vcpu_pend_interrupt(targ, vector);
vcpu_unblock(targ);
if (running)
@@ -161,7 +159,7 @@ ia64_hypercall(struct pt_regs *regs)
if (regs->r28 == PAL_HALT_LIGHT) {
if (vcpu_deliverable_interrupts(v) ||
event_pending(v)) {
- perfc_incrc(idle_when_pending);
+ perfc_incr(idle_when_pending);
vcpu_pend_unspecified_interrupt(v);
//printk("idle w/int#%d pending!\n",pi);
//this shouldn't happen, but it apparently does quite a bit! so don't
@@ -170,7 +168,7 @@ ia64_hypercall(struct pt_regs *regs)
//as deliver_pending_interrupt is called on the way out and will deliver it
}
else {
- perfc_incrc(pal_halt_light);
+ perfc_incr(pal_halt_light);
migrate_timer(&v->arch.hlt_timer,
v->processor);
set_timer(&v->arch.hlt_timer,
@@ -209,7 +207,7 @@ ia64_hypercall(struct pt_regs *regs)
regs->r10 = x.r10; regs->r11 = x.r11;
break;
case FW_HYPERCALL_SAL_RETURN:
- if ( !test_and_set_bit(_VCPUF_down, &v->vcpu_flags) )
+ if ( !test_and_set_bit(_VPF_down, &v->pause_flags) )
vcpu_sleep_nosync(v);
break;
case FW_HYPERCALL_EFI_CALL:
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/xen/hyperprivop.S
--- a/xen/arch/ia64/xen/hyperprivop.S Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/xen/hyperprivop.S Fri Mar 30 17:18:42 2007 -0600
@@ -26,8 +26,7 @@
# define FAST_HYPERPRIVOPS
# ifdef PERF_COUNTERS
# define FAST_HYPERPRIVOP_CNT
-# define FAST_HYPERPRIVOP_PERFC(N) \
- (perfcounters + FAST_HYPERPRIVOP_PERFC_OFS + (4 * N))
+# define FAST_HYPERPRIVOP_PERFC(N) PERFC(fast_hyperprivop + N)
# define FAST_REFLECT_CNT
# endif
@@ -364,7 +363,7 @@ GLOBAL_ENTRY(fast_tick_reflect)
mov rp=r29;;
mov cr.itm=r26;; // ensure next tick
#ifdef FAST_REFLECT_CNT
- movl r20=perfcounters+FAST_REFLECT_PERFC_OFS+((0x3000>>8)*4);;
+ movl r20=PERFC(fast_reflect + (0x3000>>8));;
ld4 r21=[r20];;
adds r21=1,r21;;
st4 [r20]=r21;;
@@ -597,7 +596,7 @@ END(fast_break_reflect)
// r31 == pr
ENTRY(fast_reflect)
#ifdef FAST_REFLECT_CNT
- movl r22=perfcounters+FAST_REFLECT_PERFC_OFS;
+ movl r22=PERFC(fast_reflect);
shr r23=r20,8-2;;
add r22=r22,r23;;
ld4 r21=[r22];;
@@ -938,7 +937,7 @@ 1: // check the guest VHPT
(p7) br.cond.spnt.few page_not_present;;
#ifdef FAST_REFLECT_CNT
- movl r21=perfcounter+FAST_VHPT_TRANSLATE_PERFC_OFS;;
+ movl r21=PERFC(fast_vhpt_translate);;
ld4 r22=[r21];;
adds r22=1,r22;;
st4 [r21]=r22;;
@@ -968,7 +967,7 @@ END(fast_tlb_miss_reflect)
// we get here if fast_insert fails (e.g. due to metaphysical lookup)
ENTRY(recover_and_page_fault)
#ifdef PERF_COUNTERS
- movl r21=perfcounters + RECOVER_TO_PAGE_FAULT_PERFC_OFS;;
+ movl r21=PERFC(recover_to_page_fault);;
ld4 r22=[r21];;
adds r22=1,r22;;
st4 [r21]=r22;;
@@ -1832,7 +1831,7 @@ END(hyper_ptc_ga)
// recovery block for hyper_itc metaphysical memory lookup
ENTRY(recover_and_dispatch_break_fault)
#ifdef PERF_COUNTERS
- movl r21=perfcounters + RECOVER_TO_BREAK_FAULT_PERFC_OFS;;
+ movl r21=PERFC(recover_to_break_fault);;
ld4 r22=[r21];;
adds r22=1,r22;;
st4 [r21]=r22;;
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/xen/mm.c
--- a/xen/arch/ia64/xen/mm.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/xen/mm.c Fri Mar 30 17:18:42 2007 -0600
@@ -400,7 +400,7 @@ share_xen_page_with_guest(struct page_in
ASSERT(page->count_info == 0);
/* Only add to the allocation list if the domain isn't dying. */
- if ( !test_bit(_DOMF_dying, &d->domain_flags) )
+ if ( !d->is_dying )
{
page->count_info |= PGC_allocated | 1;
if ( unlikely(d->xenheap_pages++ == 0) )
@@ -1131,7 +1131,7 @@ assign_domain_page_replace(struct domain
domain_put_page(d, mpaddr, pte, old_pte, 1);
}
}
- perfc_incrc(assign_domain_page_replace);
+ perfc_incr(assign_domain_page_replace);
}
// caller must get_page(new_page) before
@@ -1207,7 +1207,7 @@ assign_domain_page_cmpxchg_rel(struct do
}
domain_page_flush_and_put(d, mpaddr, pte, old_pte, old_page);
- perfc_incrc(assign_domain_pge_cmpxchg_rel);
+ perfc_incr(assign_domain_pge_cmpxchg_rel);
return 0;
}
@@ -1266,7 +1266,7 @@ zap_domain_page_one(struct domain *d, un
BUG_ON(clear_PGC_allocate && (page_get_owner(page) == NULL));
domain_put_page(d, mpaddr, pte, old_pte, clear_PGC_allocate);
- perfc_incrc(zap_dcomain_page_one);
+ perfc_incr(zap_dcomain_page_one);
}
unsigned long
@@ -1279,7 +1279,7 @@ dom0vp_zap_physmap(struct domain *d, uns
}
zap_domain_page_one(d, gpfn << PAGE_SHIFT, 1, INVALID_MFN);
- perfc_incrc(dom0vp_zap_physmap);
+ perfc_incr(dom0vp_zap_physmap);
return 0;
}
@@ -1333,7 +1333,7 @@ __dom0vp_add_physmap(struct domain* d, u
get_gpfn_from_mfn(mfn) != INVALID_M2P_ENTRY);
assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, flags);
//don't update p2m table because this page belongs to rd, not d.
- perfc_incrc(dom0vp_add_physmap);
+ perfc_incr(dom0vp_add_physmap);
out1:
put_domain(rd);
return error;
@@ -1503,7 +1503,7 @@ create_grant_host_mapping(unsigned long
#endif
((flags & GNTMAP_readonly) ?
ASSIGN_readonly : ASSIGN_writable));
- perfc_incrc(create_grant_host_mapping);
+ perfc_incr(create_grant_host_mapping);
return GNTST_okay;
}
@@ -1568,7 +1568,7 @@ destroy_grant_host_mapping(unsigned long
BUG_ON(pte_pgc_allocated(old_pte));
domain_page_flush_and_put(d, gpaddr, pte, old_pte, page);
- perfc_incrc(destroy_grant_host_mapping);
+ perfc_incr(destroy_grant_host_mapping);
return GNTST_okay;
}
@@ -1629,7 +1629,7 @@ steal_page(struct domain *d, struct page
free_domheap_page(new);
return -1;
}
- perfc_incrc(steal_page_refcount);
+ perfc_incr(steal_page_refcount);
}
spin_lock(&d->page_alloc_lock);
@@ -1693,7 +1693,7 @@ steal_page(struct domain *d, struct page
list_del(&page->list);
spin_unlock(&d->page_alloc_lock);
- perfc_incrc(steal_page);
+ perfc_incr(steal_page);
return 0;
}
@@ -1710,7 +1710,7 @@ guest_physmap_add_page(struct domain *d,
//BUG_ON(mfn != ((lookup_domain_mpa(d, gpfn << PAGE_SHIFT) & _PFN_MASK) >>
PAGE_SHIFT));
- perfc_incrc(guest_physmap_add_page);
+ perfc_incr(guest_physmap_add_page);
}
void
@@ -1719,7 +1719,7 @@ guest_physmap_remove_page(struct domain
{
BUG_ON(mfn == 0);//XXX
zap_domain_page_one(d, gpfn << PAGE_SHIFT, 0, mfn);
- perfc_incrc(guest_physmap_remove_page);
+ perfc_incr(guest_physmap_remove_page);
}
static void
@@ -1799,7 +1799,7 @@ domain_page_flush_and_put(struct domain*
break;
}
#endif
- perfc_incrc(domain_page_flush_and_put);
+ perfc_incr(domain_page_flush_and_put);
}
int
@@ -1935,8 +1935,7 @@ void put_page_type(struct page_info *pag
* page-table pages if we detect a referential loop.
* See domain.c:relinquish_list().
*/
- ASSERT((x & PGT_validated) ||
- test_bit(_DOMF_dying, &page_get_owner(page)->domain_flags));
+ ASSERT((x & PGT_validated) || page_get_owner(page)->is_dying);
if ( unlikely((nx & PGT_count_mask) == 0) )
{
@@ -1996,7 +1995,7 @@ int get_page_type(struct page_info *page
if ( unlikely(!cpus_empty(mask)) )
{
- perfc_incrc(need_flush_tlb_flush);
+ perfc_incr(need_flush_tlb_flush);
flush_tlb_mask(mask);
}
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/xen/privop.c
--- a/xen/arch/ia64/xen/privop.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/xen/privop.c Fri Mar 30 17:18:42 2007 -0600
@@ -641,15 +641,15 @@ static IA64FAULT priv_handle_op(VCPU * v
if (inst.M29.x3 != 0)
break;
if (inst.M30.x4 == 8 && inst.M30.x2 == 2) {
- perfc_incrc(mov_to_ar_imm);
+ perfc_incr(mov_to_ar_imm);
return priv_mov_to_ar_imm(vcpu, inst);
}
if (inst.M44.x4 == 6) {
- perfc_incrc(ssm);
+ perfc_incr(ssm);
return priv_ssm(vcpu, inst);
}
if (inst.M44.x4 == 7) {
- perfc_incrc(rsm);
+ perfc_incr(rsm);
return priv_rsm(vcpu, inst);
}
break;
@@ -658,9 +658,9 @@ static IA64FAULT priv_handle_op(VCPU * v
x6 = inst.M29.x6;
if (x6 == 0x2a) {
if (privify_en && inst.M29.r2 > 63 && inst.M29.ar3 < 8)
- perfc_incrc(mov_from_ar); // privified mov from
kr
+ perfc_incr(mov_from_ar); // privified mov from
kr
else
- perfc_incrc(mov_to_ar_reg);
+ perfc_incr(mov_to_ar_reg);
return priv_mov_to_ar_reg(vcpu, inst);
}
if (inst.M29.x3 != 0)
@@ -676,9 +676,9 @@ static IA64FAULT priv_handle_op(VCPU * v
}
}
if (privify_en && x6 == 52 && inst.M28.r3 > 63)
- perfc_incrc(fc);
+ perfc_incr(fc);
else if (privify_en && x6 == 16 && inst.M43.r3 > 63)
- perfc_incrc(cpuid);
+ perfc_incr(cpuid);
else
perfc_incra(misc_privop, x6);
return (*pfunc) (vcpu, inst);
@@ -688,23 +688,23 @@ static IA64FAULT priv_handle_op(VCPU * v
break;
if (inst.B8.x6 == 0x08) {
IA64FAULT fault;
- perfc_incrc(rfi);
+ perfc_incr(rfi);
fault = priv_rfi(vcpu, inst);
if (fault == IA64_NO_FAULT)
fault = IA64_RFI_IN_PROGRESS;
return fault;
}
if (inst.B8.x6 == 0x0c) {
- perfc_incrc(bsw0);
+ perfc_incr(bsw0);
return priv_bsw0(vcpu, inst);
}
if (inst.B8.x6 == 0x0d) {
- perfc_incrc(bsw1);
+ perfc_incr(bsw1);
return priv_bsw1(vcpu, inst);
}
if (inst.B8.x6 == 0x0) {
// break instr for privified cover
- perfc_incrc(cover);
+ perfc_incr(cover);
return priv_cover(vcpu, inst);
}
break;
@@ -713,7 +713,7 @@ static IA64FAULT priv_handle_op(VCPU * v
break;
#if 0
if (inst.I26.x6 == 0 && inst.I26.x3 == 0) {
- perfc_incrc(cover);
+ perfc_incr(cover);
return priv_cover(vcpu, inst);
}
#endif
@@ -721,13 +721,13 @@ static IA64FAULT priv_handle_op(VCPU * v
break; // I26.x3 == I27.x3
if (inst.I26.x6 == 0x2a) {
if (privify_en && inst.I26.r2 > 63 && inst.I26.ar3 < 8)
- perfc_incrc(mov_from_ar); // privified
mov from kr
+ perfc_incr(mov_from_ar); // privified
mov from kr
else
- perfc_incrc(mov_to_ar_reg);
+ perfc_incr(mov_to_ar_reg);
return priv_mov_to_ar_reg(vcpu, inst);
}
if (inst.I27.x6 == 0x0a) {
- perfc_incrc(mov_to_ar_imm);
+ perfc_incr(mov_to_ar_imm);
return priv_mov_to_ar_imm(vcpu, inst);
}
break;
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/xen/privop_stat.c
--- a/xen/arch/ia64/xen/privop_stat.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/xen/privop_stat.c Fri Mar 30 17:18:42 2007 -0600
@@ -10,48 +10,39 @@ struct privop_addr_count {
unsigned long addr[PRIVOP_COUNT_NADDRS];
unsigned int count[PRIVOP_COUNT_NADDRS];
unsigned int overflow;
- atomic_t *perfc_addr;
- atomic_t *perfc_count;
- atomic_t *perfc_overflow;
};
-#undef PERFCOUNTER
+struct privop_addr_info {
+ enum perfcounter perfc_addr;
+ enum perfcounter perfc_count;
+ enum perfcounter perfc_overflow;
+};
+
#define PERFCOUNTER(var, name)
-
-#undef PERFCOUNTER_CPU
-#define PERFCOUNTER_CPU(var, name)
-
-#undef PERFCOUNTER_ARRAY
#define PERFCOUNTER_ARRAY(var, name, size)
-#undef PERFSTATUS
#define PERFSTATUS(var, name)
-
-#undef PERFSTATUS_CPU
-#define PERFSTATUS_CPU(var, name)
-
-#undef PERFSTATUS_ARRAY
#define PERFSTATUS_ARRAY(var, name, size)
-#undef PERFPRIVOPADDR
#define PERFPRIVOPADDR(name) \
{ \
- { 0 }, { 0 }, 0, \
- perfcounters.privop_addr_##name##_addr, \
- perfcounters.privop_addr_##name##_count, \
- perfcounters.privop_addr_##name##_overflow \
+ PERFC_privop_addr_##name##_addr, \
+ PERFC_privop_addr_##name##_count, \
+ PERFC_privop_addr_##name##_overflow \
},
-static struct privop_addr_count privop_addr_counter[] = {
+static const struct privop_addr_info privop_addr_info[] = {
#include <asm/perfc_defn.h>
};
#define PRIVOP_COUNT_NINSTS \
- (sizeof(privop_addr_counter) / sizeof(privop_addr_counter[0]))
+ (sizeof(privop_addr_info) / sizeof(privop_addr_info[0]))
+
+static DEFINE_PER_CPU(struct privop_addr_count[PRIVOP_COUNT_NINSTS],
privop_addr_counter);
void privop_count_addr(unsigned long iip, enum privop_inst inst)
{
- struct privop_addr_count *v = &privop_addr_counter[inst];
+ struct privop_addr_count *v = this_cpu(privop_addr_counter) + inst;
int i;
if (inst >= PRIVOP_COUNT_NINSTS)
@@ -72,31 +63,44 @@ void privop_count_addr(unsigned long iip
void gather_privop_addrs(void)
{
- int i, j;
- atomic_t *v;
- for (i = 0; i < PRIVOP_COUNT_NINSTS; i++) {
- /* Note: addresses are truncated! */
- v = privop_addr_counter[i].perfc_addr;
- for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
- atomic_set(&v[j], privop_addr_counter[i].addr[j]);
+ unsigned int cpu;
- v = privop_addr_counter[i].perfc_count;
- for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
- atomic_set(&v[j], privop_addr_counter[i].count[j]);
+ for_each_cpu ( cpu ) {
+ perfc_t *perfcounters = per_cpu(perfcounters, cpu);
+ struct privop_addr_count *s = per_cpu(privop_addr_counter, cpu);
+ int i, j;
+
+ for (i = 0; i < PRIVOP_COUNT_NINSTS; i++, s++) {
+ perfc_t *d;
+
+ /* Note: addresses are truncated! */
+ d = perfcounters + privop_addr_info[i].perfc_addr;
+ for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
+ d[j] = s->addr[j];
+
+ d = perfcounters + privop_addr_info[i].perfc_count;
+ for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
+ d[j] = s->count[j];
- atomic_set(privop_addr_counter[i].perfc_overflow,
- privop_addr_counter[i].overflow);
+ perfcounters[privop_addr_info[i].perfc_overflow] =
+ s->overflow;
+ }
}
}
void reset_privop_addrs(void)
{
- int i, j;
- for (i = 0; i < PRIVOP_COUNT_NINSTS; i++) {
- struct privop_addr_count *v = &privop_addr_counter[i];
- for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
- v->addr[j] = v->count[j] = 0;
- v->overflow = 0;
+ unsigned int cpu;
+
+ for_each_cpu ( cpu ) {
+ struct privop_addr_count *v = per_cpu(privop_addr_counter, cpu);
+ int i, j;
+
+ for (i = 0; i < PRIVOP_COUNT_NINSTS; i++, v++) {
+ for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
+ v->addr[j] = v->count[j] = 0;
+ v->overflow = 0;
+ }
}
}
#endif
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/xen/tlb_track.c
--- a/xen/arch/ia64/xen/tlb_track.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/xen/tlb_track.c Fri Mar 30 17:18:42 2007 -0600
@@ -216,14 +216,14 @@ tlb_track_insert_or_dirty(struct tlb_tra
TLB_TRACK_RET_T ret = TLB_TRACK_NOT_FOUND;
#if 0 /* this is done at vcpu_tlb_track_insert_or_dirty() */
- perfc_incrc(tlb_track_iod);
+ perfc_incr(tlb_track_iod);
if (!pte_tlb_tracking(old_pte)) {
- perfc_incrc(tlb_track_iod_not_tracked);
+ perfc_incr(tlb_track_iod_not_tracked);
return TLB_TRACK_NOT_TRACKED;
}
#endif
if (pte_tlb_inserted_many(old_pte)) {
- perfc_incrc(tlb_track_iod_tracked_many);
+ perfc_incr(tlb_track_iod_tracked_many);
return TLB_TRACK_MANY;
}
@@ -260,7 +260,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
if (entry->vaddr == vaddr && entry->rid == rid) {
// tlb_track_printd("TLB_TRACK_FOUND\n");
ret = TLB_TRACK_FOUND;
- perfc_incrc(tlb_track_iod_found);
+ perfc_incr(tlb_track_iod_found);
#ifdef CONFIG_TLB_TRACK_CNT
entry->cnt++;
if (entry->cnt > TLB_TRACK_CNT_FORCE_MANY) {
@@ -276,7 +276,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
*/
// tlb_track_entry_printf(entry);
// tlb_track_printd("cnt = %ld\n", entry->cnt);
- perfc_incrc(tlb_track_iod_force_many);
+ perfc_incr(tlb_track_iod_force_many);
goto force_many;
}
#endif
@@ -294,14 +294,14 @@ tlb_track_insert_or_dirty(struct tlb_tra
if (pte_val(ret_pte) != pte_val(old_pte)) {
// tlb_track_printd("TLB_TRACK_AGAIN\n");
ret = TLB_TRACK_AGAIN;
- perfc_incrc(tlb_track_iod_again);
+ perfc_incr(tlb_track_iod_again);
} else {
// tlb_track_printd("TLB_TRACK_MANY del entry 0x%p\n",
// entry);
ret = TLB_TRACK_MANY;
list_del(&entry->list);
// tlb_track_entry_printf(entry);
- perfc_incrc(tlb_track_iod_tracked_many_del);
+ perfc_incr(tlb_track_iod_tracked_many_del);
}
goto out;
}
@@ -314,7 +314,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
*/
// tlb_track_printd("TLB_TRACK_AGAIN\n");
ret = TLB_TRACK_AGAIN;
- perfc_incrc(tlb_track_iod_again);
+ perfc_incr(tlb_track_iod_again);
goto out;
}
@@ -323,7 +323,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
/* Other thread else removed the tlb_track_entry after we got old_pte
before we got spin lock. */
ret = TLB_TRACK_AGAIN;
- perfc_incrc(tlb_track_iod_again);
+ perfc_incr(tlb_track_iod_again);
goto out;
}
if (new_entry == NULL && bit_to_be_set == _PAGE_TLB_INSERTED) {
@@ -334,10 +334,10 @@ tlb_track_insert_or_dirty(struct tlb_tra
/* entry can't be allocated.
fall down into full flush mode. */
bit_to_be_set |= _PAGE_TLB_INSERTED_MANY;
- perfc_incrc(tlb_track_iod_new_failed);
+ perfc_incr(tlb_track_iod_new_failed);
}
// tlb_track_printd("new_entry 0x%p\n", new_entry);
- perfc_incrc(tlb_track_iod_new_entry);
+ perfc_incr(tlb_track_iod_new_entry);
goto again;
}
@@ -348,7 +348,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
if (tlb_track_pte_zapped(old_pte, ret_pte)) {
// tlb_track_printd("zapped TLB_TRACK_AGAIN\n");
ret = TLB_TRACK_AGAIN;
- perfc_incrc(tlb_track_iod_again);
+ perfc_incr(tlb_track_iod_again);
goto out;
}
@@ -359,7 +359,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
// tlb_track_printd("iserted TLB_TRACK_MANY\n");
BUG_ON(!pte_tlb_inserted(ret_pte));
ret = TLB_TRACK_MANY;
- perfc_incrc(tlb_track_iod_new_many);
+ perfc_incr(tlb_track_iod_new_many);
goto out;
}
BUG_ON(pte_tlb_inserted(ret_pte));
@@ -381,7 +381,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
#ifdef CONFIG_TLB_TRACK_CNT
entry->cnt = 0;
#endif
- perfc_incrc(tlb_track_iod_insert);
+ perfc_incr(tlb_track_iod_insert);
// tlb_track_entry_printf(entry);
} else {
goto out;
@@ -392,7 +392,7 @@ tlb_track_insert_or_dirty(struct tlb_tra
cpu_set(v->processor, entry->pcpu_dirty_mask);
BUG_ON(v->vcpu_id >= NR_CPUS);
vcpu_set(v->vcpu_id, entry->vcpu_dirty_mask);
- perfc_incrc(tlb_track_iod_dirtied);
+ perfc_incr(tlb_track_iod_dirtied);
out:
spin_unlock(&tlb_track->hash_lock);
@@ -432,19 +432,19 @@ tlb_track_search_and_remove(struct tlb_t
struct list_head* head = tlb_track_hash_head(tlb_track, ptep);
struct tlb_track_entry* entry;
- perfc_incrc(tlb_track_sar);
+ perfc_incr(tlb_track_sar);
if (!pte_tlb_tracking(old_pte)) {
- perfc_incrc(tlb_track_sar_not_tracked);
+ perfc_incr(tlb_track_sar_not_tracked);
return TLB_TRACK_NOT_TRACKED;
}
if (!pte_tlb_inserted(old_pte)) {
BUG_ON(pte_tlb_inserted_many(old_pte));
- perfc_incrc(tlb_track_sar_not_found);
+ perfc_incr(tlb_track_sar_not_found);
return TLB_TRACK_NOT_FOUND;
}
if (pte_tlb_inserted_many(old_pte)) {
BUG_ON(!pte_tlb_inserted(old_pte));
- perfc_incrc(tlb_track_sar_many);
+ perfc_incr(tlb_track_sar_many);
return TLB_TRACK_MANY;
}
@@ -475,14 +475,14 @@ tlb_track_search_and_remove(struct tlb_t
pte_tlb_inserted(current_pte))) {
BUG_ON(pte_tlb_inserted_many(current_pte));
spin_unlock(&tlb_track->hash_lock);
- perfc_incrc(tlb_track_sar_many);
+ perfc_incr(tlb_track_sar_many);
return TLB_TRACK_MANY;
}
list_del(&entry->list);
spin_unlock(&tlb_track->hash_lock);
*entryp = entry;
- perfc_incrc(tlb_track_sar_found);
+ perfc_incr(tlb_track_sar_found);
// tlb_track_entry_printf(entry);
#ifdef CONFIG_TLB_TRACK_CNT
// tlb_track_printd("cnt = %ld\n", entry->cnt);
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/xen/vcpu.c
--- a/xen/arch/ia64/xen/vcpu.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/xen/vcpu.c Fri Mar 30 17:18:42 2007 -0600
@@ -1616,7 +1616,7 @@ IA64FAULT vcpu_translate(VCPU * vcpu, u6
*pteval = (address & _PAGE_PPN_MASK) |
__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX;
*itir = PAGE_SHIFT << 2;
- perfc_incrc(phys_translate);
+ perfc_incr(phys_translate);
return IA64_NO_FAULT;
}
} else if (!region && warn_region0_address) {
@@ -1637,7 +1637,7 @@ IA64FAULT vcpu_translate(VCPU * vcpu, u6
if (trp != NULL) {
*pteval = trp->pte.val;
*itir = trp->itir;
- perfc_incrc(tr_translate);
+ perfc_incr(tr_translate);
return IA64_NO_FAULT;
}
}
@@ -1647,7 +1647,7 @@ IA64FAULT vcpu_translate(VCPU * vcpu, u6
if (trp != NULL) {
*pteval = trp->pte.val;
*itir = trp->itir;
- perfc_incrc(tr_translate);
+ perfc_incr(tr_translate);
return IA64_NO_FAULT;
}
}
@@ -1660,7 +1660,7 @@ IA64FAULT vcpu_translate(VCPU * vcpu, u6
&& vcpu_match_tr_entry_no_p(trp, address, rid)) {
*pteval = pte.val;
*itir = trp->itir;
- perfc_incrc(dtlb_translate);
+ perfc_incr(dtlb_translate);
return IA64_USE_TLB;
}
@@ -1709,7 +1709,7 @@ out:
out:
*itir = rr & RR_PS_MASK;
*pteval = pte.val;
- perfc_incrc(vhpt_translate);
+ perfc_incr(vhpt_translate);
return IA64_NO_FAULT;
}
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/ia64/xen/vhpt.c
--- a/xen/arch/ia64/xen/vhpt.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/ia64/xen/vhpt.c Fri Mar 30 17:18:42 2007 -0600
@@ -48,14 +48,14 @@ local_vhpt_flush(void)
/* this must be after flush */
tlbflush_update_time(&__get_cpu_var(vhpt_tlbflush_timestamp),
flush_time);
- perfc_incrc(local_vhpt_flush);
+ perfc_incr(local_vhpt_flush);
}
void
vcpu_vhpt_flush(struct vcpu* v)
{
__vhpt_flush(vcpu_vhpt_maddr(v));
- perfc_incrc(vcpu_vhpt_flush);
+ perfc_incr(vcpu_vhpt_flush);
}
static void
@@ -184,7 +184,7 @@ domain_purge_swtc_entries(struct domain
{
struct vcpu* v;
for_each_vcpu(d, v) {
- if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
+ if (!v->is_initialised)
continue;
/* Purge TC entries.
@@ -202,7 +202,7 @@ domain_purge_swtc_entries_vcpu_dirty_mas
for_each_vcpu_mask(vcpu, vcpu_dirty_mask) {
struct vcpu* v = d->vcpu[vcpu];
- if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
+ if (!v->is_initialised)
continue;
/* Purge TC entries.
@@ -248,7 +248,7 @@ void vcpu_flush_vtlb_all(struct vcpu *v)
not running on this processor. There is currently no easy way to
check this. */
- perfc_incrc(vcpu_flush_vtlb_all);
+ perfc_incr(vcpu_flush_vtlb_all);
}
static void __vcpu_flush_vtlb_all(void *vcpu)
@@ -263,7 +263,7 @@ void domain_flush_vtlb_all(struct domain
struct vcpu *v;
for_each_vcpu(d, v) {
- if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
+ if (!v->is_initialised)
continue;
if (v->processor == cpu)
@@ -280,7 +280,7 @@ void domain_flush_vtlb_all(struct domain
__vcpu_flush_vtlb_all,
v, 1, 1);
}
- perfc_incrc(domain_flush_vtlb_all);
+ perfc_incr(domain_flush_vtlb_all);
}
// Callers may need to call smp_mb() before/after calling this.
@@ -322,7 +322,7 @@ void vcpu_flush_tlb_vhpt_range (u64 vadr
vadr, 1UL << log_range);
ia64_ptcl(vadr, log_range << 2);
ia64_srlz_i();
- perfc_incrc(vcpu_flush_tlb_vhpt_range);
+ perfc_incr(vcpu_flush_tlb_vhpt_range);
}
void domain_flush_vtlb_range (struct domain *d, u64 vadr, u64 addr_range)
@@ -341,7 +341,7 @@ void domain_flush_vtlb_range (struct dom
smp_mb();
for_each_vcpu (d, v) {
- if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
+ if (!v->is_initialised)
continue;
if (HAS_PERVCPU_VHPT(d)) {
@@ -361,7 +361,7 @@ void domain_flush_vtlb_range (struct dom
/* ptc.ga */
platform_global_tlb_purge(vadr, vadr + addr_range, PAGE_SHIFT);
- perfc_incrc(domain_flush_vtlb_range);
+ perfc_incr(domain_flush_vtlb_range);
}
#ifdef CONFIG_XEN_IA64_TLB_TRACK
@@ -391,11 +391,11 @@ __domain_flush_vtlb_track_entry(struct d
*/
vcpu_get_rr(current, VRN7 << VRN_SHIFT, &rr7_rid);
if (likely(rr7_rid == entry->rid)) {
- perfc_incrc(tlb_track_use_rr7);
+ perfc_incr(tlb_track_use_rr7);
} else {
swap_rr0 = 1;
vaddr = (vaddr << 3) >> 3;// force vrn0
- perfc_incrc(tlb_track_swap_rr0);
+ perfc_incr(tlb_track_swap_rr0);
}
// tlb_track_entry_printf(entry);
@@ -407,7 +407,7 @@ __domain_flush_vtlb_track_entry(struct d
if (HAS_PERVCPU_VHPT(d)) {
for_each_vcpu_mask(vcpu, entry->vcpu_dirty_mask) {
v = d->vcpu[vcpu];
- if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
+ if (!v->is_initialised)
continue;
/* Invalidate VHPT entries. */
@@ -435,18 +435,18 @@ __domain_flush_vtlb_track_entry(struct d
/* ptc.ga */
if (local_purge) {
ia64_ptcl(vaddr, PAGE_SHIFT << 2);
- perfc_incrc(domain_flush_vtlb_local);
+ perfc_incr(domain_flush_vtlb_local);
} else {
/* ptc.ga has release semantics. */
platform_global_tlb_purge(vaddr, vaddr + PAGE_SIZE,
PAGE_SHIFT);
- perfc_incrc(domain_flush_vtlb_global);
+ perfc_incr(domain_flush_vtlb_global);
}
if (swap_rr0) {
vcpu_set_rr(current, 0, old_rid);
}
- perfc_incrc(domain_flush_vtlb_track_entry);
+ perfc_incr(domain_flush_vtlb_track_entry);
}
void
@@ -512,7 +512,7 @@ void gather_vhpt_stats(void)
for (i = 0; i < VHPT_NUM_ENTRIES; i++, v++)
if (!(v->ti_tag & INVALID_TI_TAG))
vhpt_valid++;
- perfc_seta(vhpt_valid_entries, cpu, vhpt_valid);
- }
-}
-#endif
+ per_cpu(perfcounters, cpu)[PERFC_vhpt_valid_entries] =
vhpt_valid;
+ }
+}
+#endif
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/powerpc/backtrace.c
--- a/xen/arch/powerpc/backtrace.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/powerpc/backtrace.c Fri Mar 30 17:18:42 2007 -0600
@@ -205,21 +205,6 @@ void show_backtrace_regs(struct cpu_user
console_end_sync();
}
-void __warn(char *file, int line)
-{
- ulong sp;
- ulong lr;
-
- console_start_sync();
- printk("WARN at %s:%d\n", file, line);
-
- sp = (ulong)__builtin_frame_address(0);
- lr = (ulong)__builtin_return_address(0);
- backtrace(sp, lr, lr);
-
- console_end_sync();
-}
-
void dump_execution_state(void)
{
struct cpu_user_regs *regs = guest_cpu_user_regs();
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/powerpc/domain.c
--- a/xen/arch/powerpc/domain.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/powerpc/domain.c Fri Mar 30 17:18:42 2007 -0600
@@ -168,10 +168,13 @@ int arch_set_info_guest(struct vcpu *v,
d->shared_info->wc_nsec = dom0->shared_info->wc_nsec;
d->shared_info->arch.boot_timebase = dom0->shared_info->arch.boot_timebase;
- /* Auto-online VCPU0 when it is initialised. */
- if ( !test_and_set_bit(_VCPUF_initialised, &v->vcpu_flags) &&
- (v->vcpu_id == 0) )
- clear_bit(_VCPUF_down, &v->vcpu_flags);
+ if ( !v->is_initialised )
+ {
+ v->is_initialised = 1;
+ /* Auto-online VCPU0 when it is initialised. */
+ if ( v->vcpu_id == 0 )
+ clear_bit(_VPF_down, &v->pause_flags);
+ }
cpu_init_vcpu(v);
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/powerpc/domain_build.c
--- a/xen/arch/powerpc/domain_build.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/powerpc/domain_build.c Fri Mar 30 17:18:42 2007 -0600
@@ -273,8 +273,8 @@ int construct_dom0(struct domain *d,
ofd_dom0_fixup(d, *ofh_tree + rma, cmdline, shared_info_addr);
- set_bit(_VCPUF_initialised, &v->vcpu_flags);
- clear_bit(_VCPUF_down, &v->vcpu_flags);
+ v->is_initialised = 1;
+ clear_bit(_VPF_down, &v->pause_flags);
rc = 0;
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/powerpc/mm.c
--- a/xen/arch/powerpc/mm.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/powerpc/mm.c Fri Mar 30 17:18:42 2007 -0600
@@ -106,7 +106,7 @@ void share_xen_page_with_guest(
ASSERT(page->count_info == 0);
/* Only add to the allocation list if the domain isn't dying. */
- if ( !test_bit(_DOMF_dying, &d->domain_flags) )
+ if ( !d->is_dying )
{
page->count_info |= PGC_allocated | 1;
if ( unlikely(d->xenheap_pages++ == 0) )
@@ -218,8 +218,7 @@ void put_page_type(struct page_info *pag
* page-table pages if we detect a referential loop.
* See domain.c:relinquish_list().
*/
- ASSERT((x & PGT_validated) ||
- test_bit(_DOMF_dying, &page_get_owner(page)->domain_flags));
+ ASSERT((x & PGT_validated) || page_get_owner(page)->is_dying);
if ( unlikely((nx & PGT_count_mask) == 0) )
{
@@ -261,7 +260,7 @@ int get_page_type(struct page_info *page
if ( unlikely(!cpus_empty(mask)) )
{
- perfc_incrc(need_flush_tlb_flush);
+ perfc_incr(need_flush_tlb_flush);
flush_tlb_mask(mask);
}
@@ -402,7 +401,7 @@ void free_rma_check(struct page_info *pa
void free_rma_check(struct page_info *page)
{
if (test_bit(_PGC_page_RMA, &page->count_info)) {
- if (!test_bit(_DOMF_dying, &page_get_owner(page)->domain_flags)) {
+ if (!page_get_owner(page)->is_dying) {
panic("Attempt to free an RMA page: 0x%lx\n", page_to_mfn(page));
} else {
clear_bit(_PGC_page_RMA, &page->count_info);
@@ -439,8 +438,7 @@ ulong pfn2mfn(struct domain *d, ulong pf
mfn = d->arch.p2m[pfn];
}
#ifdef DEBUG
- if (t != PFN_TYPE_NONE &&
- (d->domain_flags & DOMF_dying) &&
+ if (t != PFN_TYPE_NONE && d->is_dying &&
page_get_owner(mfn_to_page(mfn)) != d) {
printk("%s: page type: %d owner Dom[%d]:%p expected Dom[%d]:%p\n",
__func__, t,
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/x86/Rules.mk
--- a/xen/arch/x86/Rules.mk Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/x86/Rules.mk Fri Mar 30 17:18:42 2007 -0600
@@ -59,6 +59,4 @@ HDRS += $(wildcard $(BASEDIR)/include/as
HDRS += $(wildcard $(BASEDIR)/include/asm-x86/hvm/vmx/*.h)
# Require GCC v3.4+ (to avoid issues with alignment constraints in Xen headers)
-ifneq ($(call cc-ver,$(CC),0x030400),y)
-$(error Xen requires at least gcc-3.4)
-endif
+$(call cc-ver-check,CC,0x030400,"Xen requires at least gcc-3.4")
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/x86/apic.c
--- a/xen/arch/x86/apic.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/x86/apic.c Fri Mar 30 17:18:42 2007 -0600
@@ -1076,7 +1076,7 @@ fastcall void smp_apic_timer_interrupt(s
fastcall void smp_apic_timer_interrupt(struct cpu_user_regs * regs)
{
ack_APIC_irq();
- perfc_incrc(apic_timer);
+ perfc_incr(apic_timer);
raise_softirq(TIMER_SOFTIRQ);
}
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/x86/domain.c Fri Mar 30 17:18:42 2007 -0600
@@ -274,7 +274,7 @@ int switch_native(struct domain *d)
if ( !IS_COMPAT(d) )
return 0;
- clear_bit(_DOMF_compat, &d->domain_flags);
+ d->is_compat = 0;
release_arg_xlat_area(d);
/* switch gdt */
@@ -306,7 +306,7 @@ int switch_compat(struct domain *d)
if ( IS_COMPAT(d) )
return 0;
- set_bit(_DOMF_compat, &d->domain_flags);
+ d->is_compat = 1;
/* switch gdt */
gdt_l1e = l1e_from_page(virt_to_page(compat_gdt_table), PAGE_HYPERVISOR);
@@ -563,9 +563,7 @@ int arch_set_info_guest(
#endif
}
- clear_bit(_VCPUF_fpu_initialised, &v->vcpu_flags);
- if ( flags & VGCF_I387_VALID )
- set_bit(_VCPUF_fpu_initialised, &v->vcpu_flags);
+ v->fpu_initialised = !!(flags & VGCF_I387_VALID);
v->arch.flags &= ~TF_kernel_mode;
if ( (flags & VGCF_in_kernel) || is_hvm_vcpu(v)/*???*/ )
@@ -600,7 +598,7 @@ int arch_set_info_guest(
hvm_load_cpu_guest_regs(v, &v->arch.guest_context.user_regs);
}
- if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
+ if ( v->is_initialised )
goto out;
memset(v->arch.guest_context.debugreg, 0,
@@ -699,7 +697,7 @@ int arch_set_info_guest(
update_domain_wallclock_time(d);
/* Don't redo final setup */
- set_bit(_VCPUF_initialised, &v->vcpu_flags);
+ v->is_initialised = 1;
if ( paging_mode_enabled(d) )
paging_update_paging_modes(v);
@@ -708,9 +706,9 @@ int arch_set_info_guest(
out:
if ( flags & VGCF_online )
- clear_bit(_VCPUF_down, &v->vcpu_flags);
+ clear_bit(_VPF_down, &v->pause_flags);
else
- set_bit(_VCPUF_down, &v->vcpu_flags);
+ set_bit(_VPF_down, &v->pause_flags);
return 0;
#undef c
}
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/x86/domain_build.c Fri Mar 30 17:18:42 2007 -0600
@@ -254,7 +254,7 @@ int construct_dom0(struct domain *d,
/* Sanity! */
BUG_ON(d->domain_id != 0);
BUG_ON(d->vcpu[0] == NULL);
- BUG_ON(test_bit(_VCPUF_initialised, &v->vcpu_flags));
+ BUG_ON(v->is_initialised);
printk("*** LOADING DOMAIN 0 ***\n");
@@ -324,7 +324,7 @@ int construct_dom0(struct domain *d,
{
l1_pgentry_t gdt_l1e;
- set_bit(_DOMF_compat, &d->domain_flags);
+ d->is_compat = 1;
v->vcpu_info = (void *)&d->shared_info->compat.vcpu_info[0];
if ( nr_pages != (unsigned int)nr_pages )
@@ -901,8 +901,8 @@ int construct_dom0(struct domain *d,
update_domain_wallclock_time(d);
- set_bit(_VCPUF_initialised, &v->vcpu_flags);
- clear_bit(_VCPUF_down, &v->vcpu_flags);
+ v->is_initialised = 1;
+ clear_bit(_VPF_down, &v->pause_flags);
/*
* Initial register values:
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/x86/domctl.c Fri Mar 30 17:18:42 2007 -0600
@@ -448,9 +448,9 @@ void arch_get_info_guest(struct vcpu *v,
#endif
c(flags &= ~(VGCF_i387_valid|VGCF_in_kernel));
- if ( test_bit(_VCPUF_fpu_initialised, &v->vcpu_flags) )
+ if ( v->fpu_initialised )
c(flags |= VGCF_i387_valid);
- if ( !test_bit(_VCPUF_down, &v->vcpu_flags) )
+ if ( !test_bit(_VPF_down, &v->pause_flags) )
c(flags |= VGCF_online);
if ( is_hvm_vcpu(v) )
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/x86/extable.c
--- a/xen/arch/x86/extable.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/x86/extable.c Fri Mar 30 17:18:42 2007 -0600
@@ -72,7 +72,7 @@ search_pre_exception_table(struct cpu_us
if ( fixup )
{
dprintk(XENLOG_INFO, "Pre-exception: %p -> %p\n", _p(addr), _p(fixup));
- perfc_incrc(exception_fixed);
+ perfc_incr(exception_fixed);
}
return fixup;
}
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/x86/hvm/hvm.c Fri Mar 30 17:18:42 2007 -0600
@@ -59,11 +59,14 @@ struct hvm_function_table hvm_funcs __re
/* I/O permission bitmap is globally shared by all HVM guests. */
char __attribute__ ((__section__ (".bss.page_aligned")))
hvm_io_bitmap[3*PAGE_SIZE];
+/* MSR permission bitmap is globally shared by all HVM guests. */
+char __attribute__ ((__section__ (".bss.page_aligned")))
+ hvm_msr_bitmap[PAGE_SIZE];
void hvm_enable(struct hvm_function_table *fns)
{
- if ( hvm_enabled )
- return;
+ BUG_ON(hvm_enabled);
+ printk("HVM: %s enabled\n", fns->name);
/*
* Allow direct access to the PC debug port (it is often used for I/O
@@ -72,6 +75,9 @@ void hvm_enable(struct hvm_function_tabl
memset(hvm_io_bitmap, ~0, sizeof(hvm_io_bitmap));
clear_bit(0x80, hvm_io_bitmap);
+ /* All MSR accesses are intercepted by default. */
+ memset(hvm_msr_bitmap, ~0, sizeof(hvm_msr_bitmap));
+
hvm_funcs = *fns;
hvm_enabled = 1;
}
@@ -85,7 +91,7 @@ void hvm_stts(struct vcpu *v)
void hvm_stts(struct vcpu *v)
{
/* FPU state already dirty? Then no need to setup_fpu() lazily. */
- if ( !test_bit(_VCPUF_fpu_dirtied, &v->vcpu_flags) )
+ if ( !v->fpu_dirtied )
hvm_funcs.stts(v);
}
@@ -238,7 +244,7 @@ static int hvm_save_cpu_ctxt(struct doma
{
/* We don't need to save state for a vcpu that is down; the restore
* code will leave it down if there is nothing saved. */
- if ( test_bit(_VCPUF_down, &v->vcpu_flags) )
+ if ( test_bit(_VPF_down, &v->pause_flags) )
continue;
hvm_funcs.save_cpu_ctxt(v, &ctxt);
@@ -269,7 +275,7 @@ static int hvm_load_cpu_ctxt(struct doma
return -EINVAL;
/* Auxiliary processors should be woken immediately. */
- if ( test_and_clear_bit(_VCPUF_down, &v->vcpu_flags) )
+ if ( test_and_clear_bit(_VPF_down, &v->pause_flags) )
vcpu_wake(v);
return 0;
@@ -331,11 +337,11 @@ void hvm_vcpu_reset(struct vcpu *v)
hvm_funcs.vcpu_initialise(v);
- set_bit(_VCPUF_down, &v->vcpu_flags);
- clear_bit(_VCPUF_initialised, &v->vcpu_flags);
- clear_bit(_VCPUF_fpu_initialised, &v->vcpu_flags);
- clear_bit(_VCPUF_fpu_dirtied, &v->vcpu_flags);
- clear_bit(_VCPUF_blocked, &v->vcpu_flags);
+ set_bit(_VPF_down, &v->pause_flags);
+ clear_bit(_VPF_blocked, &v->pause_flags);
+ v->fpu_initialised = 0;
+ v->fpu_dirtied = 0;
+ v->is_initialised = 0;
vcpu_unpause(v);
}
@@ -350,13 +356,13 @@ static void hvm_vcpu_down(void)
d->domain_id, v->vcpu_id);
/* Doesn't halt us immediately, but we'll never return to guest context. */
- set_bit(_VCPUF_down, &v->vcpu_flags);
+ set_bit(_VPF_down, &v->pause_flags);
vcpu_sleep_nosync(v);
/* Any other VCPUs online? ... */
LOCK_BIGLOCK(d);
for_each_vcpu ( d, v )
- if ( !test_bit(_VCPUF_down, &v->vcpu_flags) )
+ if ( !test_bit(_VPF_down, &v->pause_flags) )
online_count++;
UNLOCK_BIGLOCK(d);
@@ -556,6 +562,7 @@ static hvm_hypercall_t *hvm_hypercall_ta
HYPERCALL(multicall),
HYPERCALL(xen_version),
HYPERCALL(event_channel_op),
+ HYPERCALL(sched_op),
HYPERCALL(hvm_op)
};
@@ -722,7 +729,7 @@ int hvm_bringup_ap(int vcpuid, int tramp
LOCK_BIGLOCK(d);
rc = -EEXIST;
- if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
+ if ( !v->is_initialised )
rc = boot_vcpu(d, vcpuid, ctxt);
UNLOCK_BIGLOCK(d);
@@ -733,7 +740,7 @@ int hvm_bringup_ap(int vcpuid, int tramp
goto out;
}
- if ( test_and_clear_bit(_VCPUF_down, &v->vcpu_flags) )
+ if ( test_and_clear_bit(_VPF_down, &v->pause_flags) )
vcpu_wake(v);
gdprintk(XENLOG_INFO, "AP %d bringup suceeded.\n", vcpuid);
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/x86/hvm/io.c
--- a/xen/arch/x86/hvm/io.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/x86/hvm/io.c Fri Mar 30 17:18:42 2007 -0600
@@ -287,12 +287,18 @@ static void set_reg_value (int size, int
}
#endif
-extern long get_reg_value(int size, int index, int seg, struct cpu_user_regs
*regs);
+long get_reg_value(int size, int index, int seg, struct cpu_user_regs *regs);
static inline void set_eflags_CF(int size, unsigned long v1,
unsigned long v2, struct cpu_user_regs *regs)
{
- unsigned long mask = (1 << (8 * size)) - 1;
+ unsigned long mask;
+
+ if ( size == BYTE_64 )
+ size = BYTE;
+ ASSERT((size <= sizeof(mask)) && (size > 0));
+
+ mask = ~0UL >> (8 * (sizeof(mask) - size));
if ((v1 & mask) > (v2 & mask))
regs->eflags |= X86_EFLAGS_CF;
@@ -301,14 +307,24 @@ static inline void set_eflags_CF(int siz
}
static inline void set_eflags_OF(int size, unsigned long v1,
- unsigned long v2, unsigned long v3, struct
cpu_user_regs *regs)
-{
- if ((v3 ^ v2) & (v3 ^ v1) & (1 << ((8 * size) - 1)))
+ unsigned long v2, unsigned long v3,
+ struct cpu_user_regs *regs)
+{
+ unsigned long mask;
+
+ if ( size == BYTE_64 )
+ size = BYTE;
+ ASSERT((size <= sizeof(mask)) && (size > 0));
+
+ mask = ~0UL >> (8 * (sizeof(mask) - size));
+
+ if ((v3 ^ v2) & (v3 ^ v1) & mask)
regs->eflags |= X86_EFLAGS_OF;
}
static inline void set_eflags_AF(int size, unsigned long v1,
- unsigned long v2, unsigned long v3, struct
cpu_user_regs *regs)
+ unsigned long v2, unsigned long v3,
+ struct cpu_user_regs *regs)
{
if ((v1 ^ v2 ^ v3) & 0x10)
regs->eflags |= X86_EFLAGS_AF;
@@ -317,7 +333,13 @@ static inline void set_eflags_ZF(int siz
static inline void set_eflags_ZF(int size, unsigned long v1,
struct cpu_user_regs *regs)
{
- unsigned long mask = (1 << (8 * size)) - 1;
+ unsigned long mask;
+
+ if ( size == BYTE_64 )
+ size = BYTE;
+ ASSERT((size <= sizeof(mask)) && (size > 0));
+
+ mask = ~0UL >> (8 * (sizeof(mask) - size));
if ((v1 & mask) == 0)
regs->eflags |= X86_EFLAGS_ZF;
@@ -326,7 +348,15 @@ static inline void set_eflags_SF(int siz
static inline void set_eflags_SF(int size, unsigned long v1,
struct cpu_user_regs *regs)
{
- if (v1 & (1 << ((8 * size) - 1)))
+ unsigned long mask;
+
+ if ( size == BYTE_64 )
+ size = BYTE;
+ ASSERT((size <= sizeof(mask)) && (size > 0));
+
+ mask = ~0UL >> (8 * (sizeof(mask) - size));
+
+ if (v1 & mask)
regs->eflags |= X86_EFLAGS_SF;
}
@@ -375,14 +405,14 @@ static void hvm_pio_assist(struct cpu_us
if ( hvm_paging_enabled(current) )
{
int rv = hvm_copy_to_guest_virt(addr, &p->data, p->size);
- if ( rv != 0 )
+ if ( rv != 0 )
{
/* Failed on the page-spanning copy. Inject PF into
* the guest for the address where we failed. */
addr += p->size - rv;
gdprintk(XENLOG_DEBUG, "Pagefault writing non-io side "
"of a page-spanning PIO: va=%#lx\n", addr);
- hvm_inject_exception(TRAP_page_fault,
+ hvm_inject_exception(TRAP_page_fault,
PFEC_write_access, addr);
return;
}
@@ -505,14 +535,14 @@ static void hvm_mmio_assist(struct cpu_u
if (hvm_paging_enabled(current))
{
int rv = hvm_copy_to_guest_virt(addr, &p->data, p->size);
- if ( rv != 0 )
+ if ( rv != 0 )
{
/* Failed on the page-spanning copy. Inject PF into
* the guest for the address where we failed. */
addr += p->size - rv;
gdprintk(XENLOG_DEBUG, "Pagefault writing non-io side of "
"a page-spanning MMIO: va=%#lx\n", addr);
- hvm_inject_exception(TRAP_page_fault,
+ hvm_inject_exception(TRAP_page_fault,
PFEC_write_access, addr);
return;
}
@@ -718,14 +748,14 @@ static void hvm_mmio_assist(struct cpu_u
case INSTR_PUSH:
mmio_opp->addr += hvm_get_segment_base(current, x86_seg_ss);
- {
+ {
unsigned long addr = mmio_opp->addr;
int rv = hvm_copy_to_guest_virt(addr, &p->data, size);
- if ( rv != 0 )
+ if ( rv != 0 )
{
addr += p->size - rv;
- gdprintk(XENLOG_DEBUG, "Pagefault emulating PUSH from MMIO: "
- "va=%#lx\n", addr);
+ gdprintk(XENLOG_DEBUG, "Pagefault emulating PUSH from MMIO:"
+ " va=%#lx\n", addr);
hvm_inject_exception(TRAP_page_fault, PFEC_write_access, addr);
return;
}
@@ -767,7 +797,7 @@ void hvm_io_assist(struct vcpu *v)
memcpy(guest_cpu_user_regs(), regs, HVM_CONTEXT_STACK_BYTES);
/* Has memory been dirtied? */
- if ( p->dir == IOREQ_READ && p->data_is_ptr )
+ if ( p->dir == IOREQ_READ && p->data_is_ptr )
{
gmfn = get_mfn_from_gpfn(paging_gva_to_gfn(v, p->data));
mark_dirty(v->domain, gmfn);
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/x86/hvm/save.c
--- a/xen/arch/x86/hvm/save.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/x86/hvm/save.c Fri Mar 30 17:18:42 2007 -0600
@@ -185,7 +185,7 @@ int hvm_load(struct domain *d, hvm_domai
/* Down all the vcpus: we only re-enable the ones that had state saved. */
for_each_vcpu(d, v)
- if ( test_and_set_bit(_VCPUF_down, &v->vcpu_flags) )
+ if ( test_and_set_bit(_VPF_down, &v->pause_flags) )
vcpu_sleep_nosync(v);
while(1) {
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/x86/hvm/svm/emulate.c
--- a/xen/arch/x86/hvm/svm/emulate.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/x86/hvm/svm/emulate.c Fri Mar 30 17:18:42 2007 -0600
@@ -373,6 +373,7 @@ MAKE_INSTR(CLTS, 2, 0x0f, 0x06);
MAKE_INSTR(CLTS, 2, 0x0f, 0x06);
MAKE_INSTR(LMSW, 3, 0x0f, 0x01, 0x00);
MAKE_INSTR(SMSW, 3, 0x0f, 0x01, 0x00);
+MAKE_INSTR(INT3, 1, 0xcc);
static const u8 *opc_bytes[INSTR_MAX_COUNT] =
{
@@ -405,7 +406,8 @@ static const u8 *opc_bytes[INSTR_MAX_COU
[INSTR_CLTS] = OPCODE_CLTS,
[INSTR_HLT] = OPCODE_HLT,
[INSTR_LMSW] = OPCODE_LMSW,
- [INSTR_SMSW] = OPCODE_SMSW
+ [INSTR_SMSW] = OPCODE_SMSW,
+ [INSTR_INT3] = OPCODE_INT3
};
/*
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/x86/hvm/svm/intr.c
--- a/xen/arch/x86/hvm/svm/intr.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/x86/hvm/svm/intr.c Fri Mar 30 17:18:42 2007 -0600
@@ -64,87 +64,73 @@ asmlinkage void svm_intr_assist(void)
{
struct vcpu *v = current;
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
- struct periodic_time *pt;
int intr_type = APIC_DM_EXTINT;
int intr_vector = -1;
- int re_injecting = 0;
- /* Check if an Injection is active */
- /* Previous Interrupt delivery caused this Intercept? */
+ /*
+ * Previous Interrupt delivery caused this intercept?
+ * This will happen if the injection is latched by the processor (hence
+ * clearing vintr.fields.irq) but then subsequently a fault occurs (e.g.,
+ * due to lack of shadow mapping of guest IDT or guest-kernel stack).
+ *
+ * NB. Exceptions that fault during delivery are lost. This needs to be
+ * fixed but we'll usually get away with it since faults are usually
+ * idempotent. But this isn't the case for e.g. software interrupts!
+ */
if ( vmcb->exitintinfo.fields.v && (vmcb->exitintinfo.fields.type == 0) )
{
- v->arch.hvm_svm.saved_irq_vector = vmcb->exitintinfo.fields.vector;
+ intr_vector = vmcb->exitintinfo.fields.vector;
vmcb->exitintinfo.bytes = 0;
- re_injecting = 1;
+ HVMTRACE_1D(REINJ_VIRQ, v, intr_vector);
+ svm_inject_extint(v, intr_vector);
+ return;
}
- /* Previous interrupt still pending? */
+ /*
+ * Previous interrupt still pending? This occurs if we return from VMRUN
+ * very early in the entry-to-guest process. Usually this is because an
+ * external physical interrupt was pending when we executed VMRUN.
+ */
if ( vmcb->vintr.fields.irq )
+ return;
+
+ /* Crank the handle on interrupt state and check for new interrrupts. */
+ pt_update_irq(v);
+ hvm_set_callback_irq_level();
+ if ( !cpu_has_pending_irq(v) )
+ return;
+
+ /*
+ * If the guest can't take an interrupt right now, create a 'fake'
+ * virtual interrupt on to intercept as soon as the guest _can_ take
+ * interrupts. Do not obtain the next interrupt from the vlapic/pic
+ * if unable to inject.
+ *
+ * Also do this if there is an exception pending. This is because
+ * the delivery of the exception can arbitrarily delay the injection
+ * of the vintr (for example, if the exception is handled via an
+ * interrupt gate, hence zeroing RFLAGS.IF). In the meantime:
+ * - the vTPR could be modified upwards, so we need to wait until the
+ * exception is delivered before we can safely decide that an
+ * interrupt is deliverable; and
+ * - the guest might look at the APIC/PIC state, so we ought not to have
+ * cleared the interrupt out of the IRR.
+ */
+ if ( irq_masked(vmcb->rflags) || vmcb->interrupt_shadow
+ || vmcb->eventinj.fields.v )
{
- intr_vector = vmcb->vintr.fields.vector;
- vmcb->vintr.bytes = 0;
- re_injecting = 1;
- }
- /* Pending IRQ saved at last VMExit? */
- else if ( v->arch.hvm_svm.saved_irq_vector >= 0 )
- {
- intr_vector = v->arch.hvm_svm.saved_irq_vector;
- v->arch.hvm_svm.saved_irq_vector = -1;
- re_injecting = 1;
- }
- /* Now let's check for newer interrrupts */
- else
- {
- pt_update_irq(v);
-
- hvm_set_callback_irq_level();
-
- if ( cpu_has_pending_irq(v) )
- {
- /*
- * Create a 'fake' virtual interrupt on to intercept as soon
- * as the guest _can_ take interrupts. Do not obtain the next
- * interrupt from the vlapic/pic if unable to inject.
- */
- if ( irq_masked(vmcb->rflags) || vmcb->interrupt_shadow )
- {
- vmcb->general1_intercepts |= GENERAL1_INTERCEPT_VINTR;
- HVMTRACE_2D(INJ_VIRQ, v, 0x0, /*fake=*/ 1);
- svm_inject_extint(v, 0x0); /* actual vector doesn't really
matter */
- return;
- }
- intr_vector = cpu_get_interrupt(v, &intr_type);
- }
+ vmcb->general1_intercepts |= GENERAL1_INTERCEPT_VINTR;
+ HVMTRACE_2D(INJ_VIRQ, v, 0x0, /*fake=*/ 1);
+ svm_inject_extint(v, 0x0); /* actual vector doesn't matter */
+ return;
}
- /* have we got an interrupt to inject? */
- if ( intr_vector < 0 )
- return;
+ /* Okay, we can deliver the interrupt: grab it and update PIC state. */
+ intr_vector = cpu_get_interrupt(v, &intr_type);
+ BUG_ON(intr_vector < 0);
- switch ( intr_type )
- {
- case APIC_DM_EXTINT:
- case APIC_DM_FIXED:
- case APIC_DM_LOWEST:
- /* Re-injecting a PIT interruptt? */
- if ( re_injecting && (pt = is_pt_irq(v, intr_vector, intr_type)) )
- ++pt->pending_intr_nr;
- /* let's inject this interrupt */
- if (re_injecting)
- HVMTRACE_1D(REINJ_VIRQ, v, intr_vector);
- else
- HVMTRACE_2D(INJ_VIRQ, v, intr_vector, /*fake=*/ 0);
- svm_inject_extint(v, intr_vector);
- break;
- case APIC_DM_SMI:
- case APIC_DM_NMI:
- case APIC_DM_INIT:
- case APIC_DM_STARTUP:
- default:
- printk("Unsupported interrupt type: %d\n", intr_type);
- BUG();
- break;
- }
+ HVMTRACE_2D(INJ_VIRQ, v, intr_vector, /*fake=*/ 0);
+ svm_inject_extint(v, intr_vector);
pt_intr_post(v, intr_vector, intr_type);
}
diff -r e7da2fcb7a22 -r fc9e2f7920c9 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Fri Mar 30 10:27:15 2007 -0600
+++ b/xen/arch/x86/hvm/svm/svm.c Fri Mar 30 17:18:42 2007 -0600
@@ -15,7 +15,6 @@
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307 USA.
- *
*/
#include <xen/config.h>
@@ -50,22 +49,15 @@
#include <asm/hvm/trace.h>
#include <asm/hap.h>
-#define SVM_EXTRA_DEBUG
-
#define set_segment_register(name, value) \
- __asm__ __volatile__ ( "movw %%ax ,%%" STR(name) "" : : "a" (value) )
-
-/* External functions. We should move these to some suitable header file(s) */
-
-extern int inst_copy_from_guest(unsigned char *buf, unsigned long guest_eip,
- int inst_len);
-extern asmlinkage void do_IRQ(struct cpu_user_regs *);
-extern void svm_dump_inst(unsigned long eip);
-extern int svm_dbg_on;
-void svm_dump_regs(const char *from, struct cpu_user_regs *regs);
-
-static int svm_do_vmmcall_reset_to_realmode(struct vcpu *v,
- struct cpu_user_regs *regs);
+ asm volatile ( "movw %%ax ,%%" STR(name) "" : : "a" (value) )
+
+int inst_copy_from_guest(unsigned char *buf, unsigned long guest_eip,
+ int inst_len);
+asmlinkage void do_IRQ(struct cpu_user_regs *);
+
+static int svm_reset_to_realmode(struct vcpu *v,
+ struct cpu_user_regs *regs);
/* va of hardware host save area */
static void *hsa[NR_CPUS] __read_mostly;
@@ -78,7 +70,6 @@ u64 root_vmcb_pa[NR_CPUS] __read_mostly;
/* hardware assisted paging bits */
extern int opt_hap_enabled;
-extern int hap_capable_system;
static inline void svm_inject_exception(struct vcpu *v, int trap,
int ev, int error_code)
@@ -213,7 +204,7 @@ static inline int long_mode_do_msr_write
switch ( ecx )
{
case MSR_EFER:
- /* offending reserved bit will cause #GP */
+ /* Offending reserved bit will cause #GP. */
if ( msr_content & ~(EFER_LME | EFER_LMA | EFER_NX | EFER_SCE) )
{
gdprintk(XENLOG_WARNING, "Trying to set reserved bit in "
@@ -221,53 +212,33 @@ static inline int long_mode_do_msr_write
goto gp_fault;
}
- /*
- * update the VMCB's EFER with the intended value along with
- * that crucial EFER.SVME bit =)
- */
- vmcb->efer = msr_content | EFER_SVME;
-
#ifdef __x86_64__
-
- /*
- * Check for EFER.LME transitions from 0->1 or 1->0. Do the
- * sanity checks and then make sure that both EFER.LME and
- * EFER.LMA are cleared. (EFER.LME can't be set in the vmcb
- * until the guest also sets CR0.PG, since even if the guest has
- * paging "disabled", the vmcb's CR0 always has PG set.)
- */
if ( (msr_content & EFER_LME) && !svm_lme_is_set(v) )
{
- /* EFER.LME transition from 0 to 1 */
-
- if ( svm_paging_enabled(v) ||
- !svm_cr4_pae_is_set(v) )
+ /* EFER.LME transition from 0 to 1. */
+ if ( svm_paging_enabled(v) || !svm_cr4_pae_is_set(v) )
{
gdprintk(XENLOG_WARNING, "Trying to set LME bit when "
"in paging mode or PAE bit is not set\n");
goto gp_fault;
}
-
- vmcb->efer &= ~(EFER_LME | EFER_LMA);
}
else if ( !(msr_content & EFER_LME) && svm_lme_is_set(v) )
{
- /* EFER.LME transistion from 1 to 0 */
-
+ /* EFER.LME transistion from 1 to 0. */
if ( svm_paging_enabled(v) )
{
gdprintk(XENLOG_WARNING,
"Trying to clear EFER.LME while paging enabled\n");
goto gp_fault;
}
-
+ }
+#endif /* __x86_64__ */
+
+ v->arch.hvm_svm.cpu_shadow_efer = msr_content;
+ vmcb->efer = msr_content | EFER_SVME;
+ if ( !svm_paging_enabled(v) )
vmcb->efer &= ~(EFER_LME | EFER_LMA);
- }
-
-#endif /* __x86_64__ */
-
- /* update the guest EFER's shadow with the intended value */
- v->arch.hvm_svm.cpu_shadow_efer = msr_content;
break;
@@ -324,9 +295,9 @@ static inline int long_mode_do_msr_write
#define loaddebug(_v,_reg) \
- __asm__ __volatile__ ("mov %0,%%db" #_reg : : "r" ((_v)->debugreg[_reg]))
+ asm volatile ("mov %0,%%db" #_reg : : "r" ((_v)->debugreg[_reg]))
#define savedebug(_v,_reg) \
- __asm__ __volatile__ ("mov %%db" #_reg ",%0" : : "r"
((_v)->debugreg[_reg]))
+ asm volatile ("mov %%db" #_reg ",%0" : : "r" ((_v)->debugreg[_reg]))
static inline void svm_save_dr(struct vcpu *v)
{
@@ -733,7 +704,7 @@ static void svm_stts(struct vcpu *v)
*/
if ( !(v->arch.hvm_svm.cpu_shadow_cr0 & X86_CR0_TS) )
{
- v->arch.hvm_svm.vmcb->exception_intercepts |= EXCEPTION_BITMAP_NM;
+ v->arch.hvm_svm.vmcb->exception_intercepts |= 1U << TRAP_no_device;
vmcb->cr0 |= X86_CR0_TS;
}
}
@@ -749,19 +720,21 @@ static void svm_init_ap_context(
struct vcpu_guest_context *ctxt, int vcpuid, int trampoline_vector)
{
struct vcpu *v;
+ struct vmcb_struct *vmcb;
cpu_user_regs_t *regs;
u16 cs_sel;
/* We know this is safe because hvm_bringup_ap() does it */
v = current->domain->vcpu[vcpuid];
+ vmcb = v->arch.hvm_svm.vmcb;
regs = &v->arch.guest_context.user_regs;
memset(ctxt, 0, sizeof(*ctxt));
/*
* We execute the trampoline code in real mode. The trampoline vector
- * passed to us is page alligned and is the physicall frame number for
- * the code. We will execute this code in real mode.
+ * passed to us is page alligned and is the physical frame number for
+ * the code. We will execute this code in real mode.
*/
cs_sel = trampoline_vector << 8;
ctxt->user_regs.eip = 0x0;
@@ -771,11 +744,11 @@ static void svm_init_ap_context(
* This is the launch of an AP; set state so that we begin executing
* the trampoline code in real-mode.
*/
- svm_do_vmmcall_reset_to_realmode(v, regs);
+ svm_reset_to_realmode(v, regs);
/* Adjust the vmcb's hidden register state. */
- v->arch.hvm_svm.vmcb->rip = 0;
- v->arch.hvm_svm.vmcb->cs.sel = cs_sel;
- v->arch.hvm_svm.vmcb->cs.base = (cs_sel << 4);
+ vmcb->rip = 0;
+ vmcb->cs.sel = cs_sel;
+ vmcb->cs.base = (cs_sel << 4);
}
static void svm_init_hypercall_page(struct domain *d, void *hypercall_page)
@@ -800,74 +773,9 @@ static void svm_init_hypercall_page(stru
*(u16 *)(hypercall_page + (__HYPERVISOR_iret * 32)) = 0x0b0f; /* ud2 */
}
-
-int svm_dbg_on = 0;
-
-static inline int svm_do_debugout(unsigned long exit_code)
-{
- int i;
-
- static unsigned long counter = 0;
- static unsigned long works[] =
- {
- VMEXIT_IOIO,
- VMEXIT_HLT,
- VMEXIT_CPUID,
- VMEXIT_DR0_READ,
- VMEXIT_DR1_READ,
- VMEXIT_DR2_READ,
- VMEXIT_DR3_READ,
- VMEXIT_DR6_READ,
- VMEXIT_DR7_READ,
- VMEXIT_DR0_WRITE,
- VMEXIT_DR1_WRITE,
- VMEXIT_DR2_WRITE,
- VMEXIT_DR3_WRITE,
- VMEXIT_CR0_READ,
- VMEXIT_CR0_WRITE,
- VMEXIT_CR3_READ,
- VMEXIT_CR4_READ,
- VMEXIT_MSR,
- VMEXIT_CR0_WRITE,
- VMEXIT_CR3_WRITE,
- VMEXIT_CR4_WRITE,
- VMEXIT_EXCEPTION_PF,
- VMEXIT_INTR,
- VMEXIT_INVLPG,
- VMEXIT_EXCEPTION_NM
- };
-
-
-#if 0
- if (svm_dbg_on && exit_code != 0x7B)
- return 1;
-#endif
-
- counter++;
-
-#if 0
- if ((exit_code == 0x4E
- || exit_code == VMEXIT_CR0_READ
- || exit_code == VMEXIT_CR0_WRITE)
- && counter < 200000)
- return 0;
-
- if ((exit_code == 0x4E) && counter < 500000)
- return 0;
-#endif
-
- for (i = 0; i < sizeof(works) / sizeof(works[0]); i++)
- if (exit_code == works[i])
- return 0;
-
- return 1;
-}
-
static void save_svm_cpu_user_regs(struct vcpu *v, struct cpu_user_regs *ctxt)
{
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-
- ASSERT(vmcb);
ctxt->eax = vmcb->rax;
ctxt->ss = vmcb->ss.sel;
@@ -882,42 +790,16 @@ static void save_svm_cpu_user_regs(struc
ctxt->ds = vmcb->ds.sel;
}
-static void svm_store_cpu_user_regs(struct cpu_user_regs *regs, struct vcpu *v)
-{
- struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-
- regs->eip = vmcb->rip;
- regs->esp = vmcb->rsp;
- regs->eflags = vmcb->rflags;
- regs->cs = vmcb->cs.sel;
- regs->ds = vmcb->ds.sel;
- regs->es = vmcb->es.sel;
- regs->ss = vmcb->ss.sel;
-}
-
-/* XXX Use svm_load_cpu_guest_regs instead */
-static void svm_load_cpu_user_regs(struct vcpu *v, struct cpu_user_regs *regs)
-{
- struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
- u32 *intercepts = &v->arch.hvm_svm.vmcb->exception_intercepts;
+static void svm_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
+{
+ struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
- /* Write the guest register value into VMCB */
vmcb->rax = regs->eax;
vmcb->ss.sel = regs->ss;
vmcb->rsp = regs->esp;
vmcb->rflags = regs->eflags | 2UL;
vmcb->cs.sel = regs->cs;
vmcb->rip = regs->eip;
- if (regs->eflags & EF_TF)
- *intercepts |= EXCEPTION_BITMAP_DB;
- else
- *intercepts &= ~EXCEPTION_BITMAP_DB;
-}
-
-static void svm_load_cpu_guest_regs(
- struct vcpu *v, struct cpu_user_regs *regs)
-{
- svm_load_cpu_user_regs(v, regs);
}
static void svm_ctxt_switch_from(struct vcpu *v)
@@ -941,8 +823,20 @@ static void svm_ctxt_switch_to(struct vc
svm_restore_dr(v);
}
-static void arch_svm_do_resume(struct vcpu *v)
-{
+static void svm_do_resume(struct vcpu *v)
+{
+ bool_t debug_state = v->domain->debugger_attached;
+
+ if ( unlikely(v->arch.hvm_vcpu.debug_state_latch != debug_state) )
+ {
+ uint32_t mask = (1U << TRAP_debug) | (1U << TRAP_int3);
+ v->arch.hvm_vcpu.debug_state_latch = debug_state;
+ if ( debug_state )
+ v->arch.hvm_svm.vmcb->exception_intercepts |= mask;
+ else
+ v->arch.hvm_svm.vmcb->exception_intercepts &= ~mask;
+ }
+
if ( v->arch.hvm_svm.launch_core != smp_processor_id() )
{
v->arch.hvm_svm.launch_core = smp_processor_id();
@@ -957,11 +851,9 @@ static int svm_vcpu_initialise(struct vc
{
int rc;
- v->arch.schedule_tail = arch_svm_do_resume;
+ v->arch.schedule_tail = svm_do_resume;
v->arch.ctxt_switch_from = svm_ctxt_switch_from;
v->arch.ctxt_switch_to = svm_ctxt_switch_to;
-
- v->arch.hvm_svm.saved_irq_vector = -1;
v->arch.hvm_svm.launch_core = -1;
@@ -997,6 +889,7 @@ static int svm_event_injection_faulted(s
}
static struct hvm_function_table svm_function_table = {
+ .name = "SVM",
.disable = stop_svm,
.vcpu_initialise = svm_vcpu_initialise,
.vcpu_destroy = svm_vcpu_destroy,
@@ -1026,16 +919,13 @@ void svm_npt_detect(void)
{
u32 eax, ebx, ecx, edx;
- /* check CPUID for nested paging support */
+ /* Check CPUID for nested paging support. */
cpuid(0x8000000A, &eax, &ebx, &ecx, &edx);
- if ( edx & 0x01 ) /* nested paging */
- {
- hap_capable_system = 1;
- }
- else if ( opt_hap_enabled )
- {
- printk(" nested paging is not supported by this CPU.\n");
- hap_capable_system = 0; /* no nested paging, we disable flag. */
+
+ if ( !(edx & 1) && opt_hap_enabled )
+ {
+ printk("SVM: Nested paging is not supported by this CPU.\n");
+ opt_hap_enabled = 0;
}
}
@@ -1050,7 +940,7 @@ int start_svm(void)
ecx = cpuid_ecx(0x80000001);
boot_cpu_data.x86_capability[5] = ecx;
- if (!(test_bit(X86_FEATURE_SVME, &boot_cpu_data.x86_capability)))
+ if ( !(test_bit(X86_FEATURE_SVME, &boot_cpu_data.x86_capability)) )
return 0;
/* check whether SVM feature is disabled in BIOS */
@@ -1061,14 +951,13 @@ int start_svm(void)
return 0;
}
- if (!hsa[cpu])
- if (!(hsa[cpu] = alloc_host_save_area()))
- return 0;
-
+ if ( ((hsa[cpu] = alloc_host_save_area()) == NULL) ||
+ ((root_vmcb[cpu] = alloc_vmcb()) == NULL) )
+ return 0;
+
rdmsr(MSR_EFER, eax, edx);
eax |= EFER_SVME;
wrmsr(MSR_EFER, eax, edx);
- printk("AMD SVM Extension is enabled for cpu %d.\n", cpu );
svm_npt_detect();
@@ -1077,14 +966,13 @@ int start_svm(void)
phys_hsa_lo = (u32) phys_hsa;
phys_hsa_hi = (u32) (phys_hsa >> 32);
wrmsr(MSR_K8_VM_HSAVE_PA, phys_hsa_lo, phys_hsa_hi);
+
+ root_vmcb_pa[cpu] = virt_to_maddr(root_vmcb[cpu]);
- if (!root_vmcb[cpu])
- if (!(root_vmcb[cpu] = alloc_vmcb()))
- return 0;
- root_vmcb_pa[cpu] = virt_to_maddr(root_vmcb[cpu]);
-
- if (cpu == 0)
- setup_vmcb_dump();
+ if ( cpu != 0 )
+ return 1;
+
+ setup_vmcb_dump();
hvm_enable(&svm_function_table);
@@ -1102,61 +990,15 @@ static int svm_do_nested_pgfault(paddr_t
return 0;
}
-
-static int svm_do_page_fault(unsigned long va, struct cpu_user_regs *regs)
-{
- HVM_DBG_LOG(DBG_LEVEL_VMMU,
- "svm_do_page_fault = 0x%lx, eip = %lx, error_code = %lx",
- va, (unsigned long)current->arch.hvm_svm.vmcb->rip,
- (unsigned long)regs->error_code);
- return paging_fault(va, regs);
-}
-
-
static void svm_do_no_device_fault(struct vmcb_struct *vmcb)
{
struct vcpu *v = current;
setup_fpu(v);
- vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_NM;
+ vmcb->exception_intercepts &= ~(1U << TRAP_no_device);
if ( !(v->arch.hvm_svm.cpu_shadow_cr0 & X86_CR0_TS) )
vmcb->cr0 &= ~X86_CR0_TS;
-}
-
-
-static void svm_do_general_protection_fault(struct vcpu *v,
- struct cpu_user_regs *regs)
-{
- struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
- unsigned long eip, error_code;
-
- ASSERT(vmcb);
-
- eip = vmcb->rip;
- error_code = vmcb->exitinfo1;
-
- if (vmcb->idtr.limit == 0) {
- printk("Huh? We got a GP Fault with an invalid IDTR!\n");
- svm_dump_vmcb(__func__, vmcb);
- svm_dump_regs(__func__, regs);
- svm_dump_inst(svm_rip2pointer(v));
- domain_crash(v->domain);
- return;
- }
-
- HVM_DBG_LOG(DBG_LEVEL_1,
- "svm_general_protection_fault: eip = %lx, erro_code = %lx",
- eip, error_code);
-
- HVM_DBG_LOG(DBG_LEVEL_1,
- "eax=%lx, ebx=%lx, ecx=%lx, edx=%lx, esi=%lx, edi=%lx",
- (unsigned long)regs->eax, (unsigned long)regs->ebx,
- (unsigned long)regs->ecx, (unsigned long)regs->edx,
- (unsigned long)regs->esi, (unsigned long)regs->edi);
-
- /* Reflect it back into the guest */
- svm_inject_exception(v, TRAP_gp_fault, 1, error_code);
}
/* Reserved bits ECX: [31:14], [12:4], [2:1]*/
@@ -1171,8 +1013,6 @@ static void svm_vmexit_do_cpuid(struct v
unsigned int eax, ebx, ecx, edx;
struct vcpu *v = current;
int inst_len;
-
- ASSERT(vmcb);
hvm_cpuid(input, &eax, &ebx, &ecx, &edx);
@@ -1305,8 +1145,8 @@ static inline unsigned long *get_reg_p(
}
-static inline unsigned long get_reg(unsigned int gpreg,
- struct cpu_user_regs *regs, struct
vmcb_struct *vmcb)
+static inline unsigned long get_reg(
+ unsigned int gpreg, struct cpu_user_regs *regs, struct vmcb_struct *vmcb)
{
unsigned long *gp;
gp = get_reg_p(gpreg, regs, vmcb);
@@ -1314,8 +1154,9 @@ static inline unsigned long get_reg(unsi
}
-static inline void set_reg(unsigned int gpreg, unsigned long value,
- struct cpu_user_regs *regs, struct vmcb_struct
*vmcb)
+static inline void set_reg(
+ unsigned int gpreg, unsigned long value,
+ struct cpu_user_regs *regs, struct vmcb_struct *vmcb)
{
unsigned long *gp;
gp = get_reg_p(gpreg, regs, vmcb);
@@ -1585,7 +1426,6 @@ static void svm_io_instruction(struct vc
ioio_info_t info;
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
- ASSERT(vmcb);
pio_opp = ¤t->arch.hvm_vcpu.io_op;
pio_opp->instr = INSTR_PIO;
pio_opp->flags = 0;
@@ -1729,226 +1569,95 @@ static void svm_io_instruction(struct vc
}
}
-static int npt_set_cr0(unsigned long value)
+static int svm_set_cr0(unsigned long value)
{
struct vcpu *v = current;
- struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-
- ASSERT(vmcb);
-
- /* ET is reserved and should be always be 1*/
- value |= X86_CR0_ET;
-
- /* Check whether the guest is about to turn on long mode.
- * If it is, set EFER.LME and EFER.LMA. Update the shadow EFER.LMA
- * bit too, so svm_long_mode_enabled() will work.
- */
- if ( (value & X86_CR0_PG) && svm_lme_is_set(v) &&
- (vmcb->cr4 & X86_CR4_PAE) && (vmcb->cr0 & X86_CR0_PE) )
- {
- v->arch.hvm_svm.cpu_shadow_efer |= EFER_LMA;
- vmcb->efer |= EFER_LMA | EFER_LME;
- }
-
- /* Whenever CR0.PG is cleared under long mode, LMA will be cleared
- * immediatly. We emulate this process for svm_long_mode_enabled().
- */
- if ( (value & (X86_CR0_PE | X86_CR0_PG)) == X86_CR0_PE )
- {
- if ( svm_long_mode_enabled(v) )
- {
- v->arch.hvm_svm.cpu_shadow_efer &= ~EFER_LMA;
- }
- }
-
- vmcb->cr0 = value | X86_CR0_WP;
- v->arch.hvm_svm.cpu_shadow_cr0 = value;
-
- /* TS cleared? Then initialise FPU now. */
- if ( !(value & X86_CR0_TS) ) {
- setup_fpu(v);
- vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_NM;
- }
-
- paging_update_paging_modes(v);
-
- return 1;
-}
-
-static int svm_set_cr0(unsigned long value)
-{
- struct vcpu *v = current;
- unsigned long mfn;
- int paging_enabled;
+ unsigned long mfn, old_value = v->arch.hvm_svm.cpu_shadow_cr0;
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
unsigned long old_base_mfn;
- ASSERT(vmcb);
-
- /* We don't want to lose PG. ET is reserved and should be always be 1*/
- paging_enabled = svm_paging_enabled(v);
+ HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR0 value = %lx\n", value);
+
+ /* ET is reserved and should be always be 1. */
value |= X86_CR0_ET;
- vmcb->cr0 = value | X86_CR0_PG | X86_CR0_WP;
- v->arch.hvm_svm.cpu_shadow_cr0 = value;
+
+ if ( (value & (X86_CR0_PE|X86_CR0_PG)) == X86_CR0_PG )
+ {
+ svm_inject_exception(v, TRAP_gp_fault, 1, 0);
+ return 0;
+ }
/* TS cleared? Then initialise FPU now. */
if ( !(value & X86_CR0_TS) )
{
setup_fpu(v);
- vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_NM;
- }
-
- HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR0 value = %lx\n", value);
-
- if ( ((value & (X86_CR0_PE | X86_CR0_PG)) == (X86_CR0_PE | X86_CR0_PG))
- && !paging_enabled )
- {
- /* The guest CR3 must be pointing to the guest physical. */
- mfn = get_mfn_from_gpfn(v->arch.hvm_svm.cpu_cr3 >> PAGE_SHIFT);
- if ( !mfn_valid(mfn) || !get_page(mfn_to_page(mfn), v->domain))
- {
- gdprintk(XENLOG_ERR, "Invalid CR3 value = %lx (mfn=%lx)\n",
- v->arch.hvm_svm.cpu_cr3, mfn);
- domain_crash(v->domain);
- return 0;
- }
-
+ vmcb->exception_intercepts &= ~(1U << TRAP_no_device);
+ }
+
+ if ( (value & X86_CR0_PG) && !(old_value & X86_CR0_PG) )
+ {
#if defined(__x86_64__)
- if ( svm_lme_is_set(v) && !svm_cr4_pae_is_set(v) )
- {
- HVM_DBG_LOG(DBG_LEVEL_1, "Enable paging before PAE enable\n");
- svm_inject_exception(v, TRAP_gp_fault, 1, 0);
- }
-
if ( svm_lme_is_set(v) )
{
+ if ( !svm_cr4_pae_is_set(v) )
+ {
+ HVM_DBG_LOG(DBG_LEVEL_1, "Enable paging before PAE enable\n");
+ svm_inject_exception(v, TRAP_gp_fault, 1, 0);
+ return 0;
+ }
HVM_DBG_LOG(DBG_LEVEL_1, "Enable the Long mode\n");
v->arch.hvm_svm.cpu_shadow_efer |= EFER_LMA;
vmcb->efer |= EFER_LMA | EFER_LME;
}
#endif /* __x86_64__ */
- /* Now arch.guest_table points to machine physical. */
- old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
- v->arch.guest_table = pagetable_from_pfn(mfn);
- if ( old_base_mfn )
- put_page(mfn_to_page(old_base_mfn));
- paging_update_paging_modes(v);
-
- HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
- (unsigned long) (mfn << PAGE_SHIFT));
- }
-
- if ( !((value & X86_CR0_PE) && (value & X86_CR0_PG)) && paging_enabled )
- if ( v->arch.hvm_svm.cpu_cr3 ) {
+ if ( !paging_mode_hap(v->domain) )
+ {
+ /* The guest CR3 must be pointing to the guest physical. */
+ mfn = get_mfn_from_gpfn(v->arch.hvm_svm.cpu_cr3 >> PAGE_SHIFT);
+ if ( !mfn_valid(mfn) || !get_page(mfn_to_page(mfn), v->domain))
+ {
+ gdprintk(XENLOG_ERR, "Invalid CR3 value = %lx (mfn=%lx)\n",
+ v->arch.hvm_svm.cpu_cr3, mfn);
+ domain_crash(v->domain);
+ return 0;
+ }
+
+ /* Now arch.guest_table points to machine physical. */
+ old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
+ v->arch.guest_table = pagetable_from_pfn(mfn);
+ if ( old_base_mfn )
+ put_page(mfn_to_page(old_base_mfn));
+
+ HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
+ (unsigned long) (mfn << PAGE_SHIFT));
+ }
+ }
+ else if ( !(value & X86_CR0_PG) && (old_value & X86_CR0_PG) )
+ {
+ /* When CR0.PG is cleared, LMA is cleared immediately. */
+ if ( svm_long_mode_enabled(v) )
+ {
+ vmcb->efer &= ~(EFER_LME | EFER_LMA);
+ v->arch.hvm_svm.cpu_shadow_efer &= ~EFER_LMA;
+ }
+
+ if ( !paging_mode_hap(v->domain) && v->arch.hvm_svm.cpu_cr3 )
+ {
put_page(mfn_to_page(get_mfn_from_gpfn(
v->arch.hvm_svm.cpu_cr3 >> PAGE_SHIFT)));
v->arch.guest_table = pagetable_null();
}
-
- /*
- * SVM implements paged real-mode and when we return to real-mode
- * we revert back to the physical mappings that the domain builder
- * created.
- */
- if ((value & X86_CR0_PE) == 0) {
- if (value & X86_CR0_PG) {
- svm_inject_exception(v, TRAP_gp_fault, 1, 0);
- return 0;
- }
+ }
+
+ vmcb->cr0 = v->arch.hvm_svm.cpu_shadow_cr0 = value;
+ if ( !paging_mode_hap(v->domain) )
+ vmcb->cr0 |= X86_CR0_PG | X86_CR0_WP;
+
+ if ( (value ^ old_value) & X86_CR0_PG )
paging_update_paging_modes(v);
- }
- else if ( (value & (X86_CR0_PE | X86_CR0_PG)) == X86_CR0_PE )
- {
- if ( svm_long_mode_enabled(v) )
- {
- vmcb->efer &= ~(EFER_LME | EFER_LMA);
- v->arch.hvm_svm.cpu_shadow_efer &= ~EFER_LMA;
- }
- /* we should take care of this kind of situation */
- paging_update_paging_modes(v);
- }
return 1;
-}
-
-//
-// nested paging functions
-//
-
-static int npt_mov_to_cr(int gpreg, int cr, struct cpu_user_regs *regs)
-{
- unsigned long value;
- struct vcpu *v = current;
- struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
- struct vlapic *vlapic = vcpu_vlapic(v);
-
- ASSERT(vmcb);
-
- value = get_reg(gpreg, regs, vmcb);
-
- switch (cr) {
- case 0:
- return npt_set_cr0(value);
-
- case 3:
- vmcb->cr3 = value;
- v->arch.hvm_svm.cpu_cr3 = value;
- break;
-
- case 4: /* CR4 */
- vmcb->cr4 = value;
- v->arch.hvm_svm.cpu_shadow_cr4 = value;
- paging_update_paging_modes(v);
- break;
-
- case 8:
- vlapic_set_reg(vlapic, APIC_TASKPRI, ((value & 0x0F) << 4));
- vmcb->vintr.fields.tpr = value & 0x0F;
- break;
-
- default:
- gdprintk(XENLOG_ERR, "invalid cr: %d\n", cr);
- domain_crash(v->domain);
- return 0;
- }
-
- return 1;
-}
-
-static void npt_mov_from_cr(int cr, int gp, struct cpu_user_regs *regs)
-{
- unsigned long value = 0;
- struct vcpu *v = current;
- struct vmcb_struct *vmcb;
- struct vlapic *vlapic = vcpu_vlapic(v);
-
- vmcb = v->arch.hvm_svm.vmcb;
- ASSERT(vmcb);
-
- switch(cr) {
- case 0:
- value = (unsigned long) v->arch.hvm_svm.cpu_shadow_cr0;
- break;
- case 2:
- value = vmcb->cr2;
- break;
- case 3:
- value = (unsigned long) v->arch.hvm_svm.cpu_cr3;
- break;
- case 4:
- value = (unsigned long) v->arch.hvm_svm.cpu_shadow_cr4;
- break;
- case 8:
- value = (unsigned long)vlapic_get_reg(vlapic, APIC_TASKPRI);
- value = (value & 0xF0) >> 4;
- break;
- default:
- domain_crash(v->domain);
- return;
- }
-
- set_reg(gp, value, regs, vmcb);
}
/*
@@ -1959,30 +1668,21 @@ static void mov_from_cr(int cr, int gp,
unsigned long value = 0;
struct vcpu *v = current;
struct vlapic *vlapic = vcpu_vlapic(v);
- struct vmcb_struct *vmcb;
-
- vmcb = v->arch.hvm_svm.vmcb;
- ASSERT(vmcb);
+ struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
switch ( cr )
{
case 0:
value = v->arch.hvm_svm.cpu_shadow_cr0;
- if (svm_dbg_on)
- printk("CR0 read =%lx \n", value );
break;
case 2:
value = vmcb->cr2;
break;
case 3:
- value = (unsigned long) v->arch.hvm_svm.cpu_cr3;
- if (svm_dbg_on)
- printk("CR3 read =%lx \n", value );
+ value = (unsigned long)v->arch.hvm_svm.cpu_cr3;
break;
case 4:
- value = (unsigned long) v->arch.hvm_svm.cpu_shadow_cr4;
- if (svm_dbg_on)
- printk("CR4 read=%lx\n", value);
+ value = (unsigned long)v->arch.hvm_svm.cpu_shadow_cr4;
break;
case 8:
value = (unsigned long)vlapic_get_reg(vlapic, APIC_TASKPRI);
@@ -2019,24 +1719,27 @@ static int mov_to_cr(int gpreg, int cr,
HVM_DBG_LOG(DBG_LEVEL_1, "mov_to_cr: CR%d, value = %lx,", cr, value);
HVM_DBG_LOG(DBG_LEVEL_1, "current = %lx,", (unsigned long) current);
- switch (cr)
+ switch ( cr )
{
case 0:
- if (svm_dbg_on)
- printk("CR0 write =%lx \n", value );
return svm_set_cr0(value);
- case 3:
- if (svm_dbg_on)
- printk("CR3 write =%lx \n", value );
+ case 3:
+ if ( paging_mode_hap(v->domain) )
+ {
+ vmcb->cr3 = v->arch.hvm_svm.cpu_cr3 = value;
+ break;
+ }
+
/* If paging is not enabled yet, simply copy the value to CR3. */
- if (!svm_paging_enabled(v)) {
+ if ( !svm_paging_enabled(v) )
+ {
v->arch.hvm_svm.cpu_cr3 = value;
break;
}
/* We make a new one if the shadow does not exist. */
- if (value == v->arch.hvm_svm.cpu_cr3)
+ if ( value == v->arch.hvm_svm.cpu_cr3 )
{
/*
* This is simple TLB flush, implying the guest has
@@ -2044,7 +1747,7 @@ static int mov_to_cr(int gpreg, int cr,
* We simply invalidate the shadow.
*/
mfn = get_mfn_from_gpfn(value >> PAGE_SHIFT);
- if (mfn != pagetable_get_pfn(v->arch.guest_table))
+ if ( mfn != pagetable_get_pfn(v->arch.guest_table) )
goto bad_cr3;
paging_update_cr3(v);
}
@@ -2056,13 +1759,13 @@ static int mov_to_cr(int gpreg, int cr,
*/
HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR3 value = %lx", value);
mfn = get_mfn_from_gpfn(value >> PAGE_SHIFT);
- if ( !mfn_valid(mfn) || !get_page(mfn_to_page(mfn), v->domain))
+ if ( !mfn_valid(mfn) || !get_page(mfn_to_page(mfn), v->domain) )
goto bad_cr3;
old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
v->arch.guest_table = pagetable_from_pfn(mfn);
- if (old_base_mfn)
+ if ( old_base_mfn )
put_page(mfn_to_page(old_base_mfn));
v->arch.hvm_svm.cpu_cr3 = value;
@@ -2072,9 +1775,13 @@ static int mov_to_cr(int gpreg, int cr,
break;
case 4: /* CR4 */
- if (svm_dbg_on)
- printk( "write cr4=%lx, cr0=%lx\n",
- value, v->arch.hvm_svm.cpu_shadow_cr0 );
+ if ( paging_mode_hap(v->domain) )
+ {
+ vmcb->cr4 = v->arch.hvm_svm.cpu_shadow_cr4 = value;
+ paging_update_paging_modes(v);
+ break;
+ }
+
old_cr = v->arch.hvm_svm.cpu_shadow_cr4;
if ( value & X86_CR4_PAE && !(old_cr & X86_CR4_PAE) )
{
@@ -2154,17 +1861,17 @@ static int svm_cr_access(struct vcpu *v,
{
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
int inst_len = 0;
- int index;
- unsigned int gpreg;
- unsigned long value;
+ int index,addr_size,i;
+ unsigned int gpreg,offset;
+ unsigned long value,addr;
u8 buffer[MAX_INST_LEN];
u8 prefix = 0;
+ u8 modrm;
+ enum x86_segment seg;
int result = 1;
enum instruction_index list_a[] = {INSTR_MOV2CR, INSTR_CLTS, INSTR_LMSW};
enum instruction_index list_b[] = {INSTR_MOVCR2, INSTR_SMSW};
enum instruction_index match;
-
- ASSERT(vmcb);
inst_copy_from_guest(buffer, svm_rip2pointer(v), sizeof(buffer));
@@ -2197,60 +1904,83 @@ static int svm_cr_access(struct vcpu *v,
{
case INSTR_MOV2CR:
gpreg = decode_src_reg(prefix, buffer[index+2]);
- if ( paging_mode_hap(v->domain) )
- result = npt_mov_to_cr(gpreg, cr, regs);
- else
- result = mov_to_cr(gpreg, cr, regs);
+ result = mov_to_cr(gpreg, cr, regs);
break;
case INSTR_MOVCR2:
gpreg = decode_src_reg(prefix, buffer[index+2]);
- if ( paging_mode_hap(v->domain) )
- npt_mov_from_cr(cr, gpreg, regs);
- else
- mov_from_cr(cr, gpreg, regs);
+ mov_from_cr(cr, gpreg, regs);
break;
case INSTR_CLTS:
/* TS being cleared means that it's time to restore fpu state. */
setup_fpu(current);
- vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_NM;
+ vmcb->exception_intercepts &= ~(1U << TRAP_no_device);
vmcb->cr0 &= ~X86_CR0_TS; /* clear TS */
v->arch.hvm_svm.cpu_shadow_cr0 &= ~X86_CR0_TS; /* clear TS */
break;
case INSTR_LMSW:
- if (svm_dbg_on)
- svm_dump_inst(svm_rip2pointer(v));
-
gpreg = decode_src_reg(prefix, buffer[index+2]);
value = get_reg(gpreg, regs, vmcb) & 0xF;
-
- if (svm_dbg_on)
- printk("CR0-LMSW value=%lx, reg=%d, inst_len=%d\n", value, gpreg,
- inst_len);
-
value = (v->arch.hvm_svm.cpu_shadow_cr0 & ~0xF) | value;
-
- if (svm_dbg_on)
- printk("CR0-LMSW CR0 - New value=%lx\n", value);
-
- if ( paging_mode_hap(v->domain) )
- result = npt_set_cr0(value);
+ result = svm_set_cr0(value);
+ break;
+
+ case INSTR_SMSW:
+ value = v->arch.hvm_svm.cpu_shadow_cr0 & 0xFFFF;
+ modrm = buffer[index+2];
+ addr_size = svm_guest_x86_mode( v );
+ if ( likely((modrm & 0xC0) >> 6 == 3) )
+ {
+ gpreg = decode_src_reg(prefix, modrm);
+ set_reg(gpreg, value, regs, vmcb);
+ }
+ /*
+ * For now, only implement decode of the offset mode, since that's the
+ * only mode observed in a real-world OS. This code is also making the
+ * assumption that we'll never hit this code in long mode.
+ */
+ else if ( (modrm == 0x26) || (modrm == 0x25) )
+ {
+ seg = x86_seg_ds;
+ i = index;
+ /* Segment or address size overrides? */
+ while ( i-- )
+ {
+ switch ( buffer[i] )
+ {
+ case 0x26: seg = x86_seg_es; break;
+ case 0x2e: seg = x86_seg_cs; break;
+ case 0x36: seg = x86_seg_ss; break;
+ case 0x64: seg = x86_seg_fs; break;
+ case 0x65: seg = x86_seg_gs; break;
+ case 0x67: addr_size ^= 6; break;
+ }
+ }
+ /* Bail unless this really is a seg_base + offset case */
+ if ( ((modrm == 0x26) && (addr_size == 4)) ||
+ ((modrm == 0x25) && (addr_size == 2)) )
+ {
+ gdprintk(XENLOG_ERR, "SMSW emulation at guest address: "
+ "%lx failed due to unhandled addressing mode."
+ "ModRM byte was: %x \n", svm_rip2pointer(v), modrm);
+ domain_crash(v->domain);
+ }
+ inst_len += addr_size;
+ offset = *(( unsigned int *) ( void *) &buffer[index + 3]);
+ offset = ( addr_size == 4 ) ? offset : ( offset & 0xFFFF );
+ addr = hvm_get_segment_base(v, seg);
+ addr += offset;
+ hvm_copy_to_guest_virt(addr,&value,2);
+ }
else
- result = svm_set_cr0(value);
- break;
-
- case INSTR_SMSW:
- if (svm_dbg_on)
- svm_dump_inst(svm_rip2pointer(v));
- value = v->arch.hvm_svm.cpu_shadow_cr0;
- gpreg = decode_src_reg(prefix, buffer[index+2]);
- set_reg(gpreg, value, regs, vmcb);
-
- if (svm_dbg_on)
- printk("CR0-SMSW value=%lx, reg=%d, inst_len=%d\n", value, gpreg,
- inst_len);
+ {
+ gdprintk(XENLOG_ERR, "SMSW emulation at guest address: %lx "
+ "failed due to unhandled addressing mode!"
+ "ModRM byte was: %x \n", svm_rip2pointer(v), modrm);
+ domain_crash(v->domain);
+ }
break;
default:
@@ -2271,8 +2001,6 @@ static inline void svm_do_msr_access(
int inst_len;
u64 msr_content=0;
u32 ecx = regs->ecx, eax, edx;
-
- ASSERT(vmcb);
HVM_DBG_LOG(DBG_LEVEL_1, "ecx=%x, eax=%x, edx=%x, exitinfo = %lx",
ecx, (u32)regs->eax, (u32)regs->edx,
@@ -2357,7 +2085,6 @@ static inline void svm_do_msr_access(
__update_guest_eip(vmcb, inst_len);
}
-
static inline void svm_vmexit_do_hlt(struct vmcb_struct *vmcb)
{
__update_guest_eip(vmcb, 1);
@@ -2372,7 +2099,6 @@ static inline void svm_vmexit_do_hlt(str
HVMTRACE_1D(HLT, current, /*int pending=*/ 0);
hvm_hlt(vmcb->rflags);
}
-
static void svm_vmexit_do_invd(struct vcpu *v)
{
@@ -2387,48 +2113,12 @@ static void svm_vmexit_do_invd(struct vc
/* Tell the user that we did this - just in case someone runs some really
* weird operating system and wants to know why it's not working...
*/
- printk("INVD instruction intercepted - ignored\n");
+ gdprintk(XENLOG_WARNING, "INVD instruction intercepted - ignored\n");
inst_len = __get_instruction_length(v, INSTR_INVD, NULL);
__update_guest_eip(vmcb, inst_len);
}
-
-
-
-#ifdef XEN_DEBUGGER
-static void svm_debug_save_cpu_user_regs(struct vmcb_struct *vmcb,
- struct cpu_user_regs *regs)
-{
- regs->eip = vmcb->rip;
- regs->esp = vmcb->rsp;
- regs->eflags = vmcb->rflags;
-
- regs->xcs = vmcb->cs.sel;
- regs->xds = vmcb->ds.sel;
- regs->xes = vmcb->es.sel;
- regs->xfs = vmcb->fs.sel;
- regs->xgs = vmcb->gs.sel;
- regs->xss = vmcb->ss.sel;
-}
-
-
-static void svm_debug_restore_cpu_user_regs(struct cpu_user_regs *regs)
-{
- vmcb->ss.sel = regs->xss;
- vmcb->rsp = regs->esp;
- vmcb->rflags = regs->eflags;
- vmcb->cs.sel = regs->xcs;
- vmcb->rip = regs->eip;
-
- vmcb->gs.sel = regs->xgs;
- vmcb->fs.sel = regs->xfs;
- vmcb->es.sel = regs->xes;
- vmcb->ds.sel = regs->xds;
-}
-#endif
-
-
void svm_handle_invlpg(const short invlpga, struct cpu_user_regs *regs)
{
struct vcpu *v = current;
@@ -2494,18 +2184,11 @@ void svm_handle_invlpg(const short invlp
*
* returns 0 on success, non-zero otherwise
*/
-static int svm_do_vmmcall_reset_to_realmode(struct vcpu *v,
- struct cpu_user_regs *regs)
-{
- struct vmcb_struct *vmcb;
-
- ASSERT(v);
- ASSERT(regs);
-
- vmcb = v->arch.hvm_svm.vmcb;
-
- ASSERT(vmcb);
-
+static int svm_reset_to_realmode(struct vcpu *v,
+ struct cpu_user_regs *regs)
+{
+ struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
+
/* clear the vmcb and user regs */
memset(regs, 0, sizeof(struct cpu_user_regs));
@@ -2587,449 +2270,65 @@ static int svm_do_vmmcall_reset_to_realm
return 0;
}
-
-void svm_dump_inst(unsigned long eip)
-{
- u8 opcode[256];
- unsigned long ptr;
- int len;
- int i;
-
- ptr = eip & ~0xff;
- len = 0;
-
- if (hvm_copy_from_guest_virt(opcode, ptr, sizeof(opcode)) == 0)
- len = sizeof(opcode);
-
- printk("Code bytes around(len=%d) %lx:", len, eip);
- for (i = 0; i < len; i++)
- {
- if ((i & 0x0f) == 0)
- printk("\n%08lx:", ptr+i);
-
- printk("%02x ", opcode[i]);
- }
-
- printk("\n");
-}
-
-
-void svm_dump_regs(const char *from, struct cpu_user_regs *regs)
-{
- struct vcpu *v = current;
- struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
- unsigned long pt = v->arch.hvm_vcpu.hw_cr3;
-
- printk("%s: guest registers from %s:\n", __func__, from);
-#if defined (__x86_64__)
- printk("rax: %016lx rbx: %016lx rcx: %016lx\n",
- regs->rax, regs->rbx, regs->rcx);
- printk("rdx: %016lx rsi: %016lx rdi: %016lx\n",
- regs->rdx, regs->rsi, regs->rdi);
- printk("rbp: %016lx rsp: %016lx r8: %016lx\n",
- regs->rbp, regs->rsp, regs->r8);
- printk("r9: %016lx r10: %016lx r11: %016lx\n",
- regs->r9, regs->r10, regs->r11);
- printk("r12: %016lx r13: %016lx r14: %016lx\n",
- regs->r12, regs->r13, regs->r14);
- printk("r15: %016lx cr0: %016lx cr3: %016lx\n",
- regs->r15, v->arch.hvm_svm.cpu_shadow_cr0, vmcb->cr3);
-#else
- printk("eax: %08x, ebx: %08x, ecx: %08x, edx: %08x\n",
- regs->eax, regs->ebx, regs->ecx, regs->edx);
- printk("edi: %08x, esi: %08x, ebp: %08x, esp: %08x\n",
- regs->edi, regs->esi, regs->ebp, regs->esp);
- printk("%s: guest cr0: %lx\n", __func__,
- v->arch.hvm_svm.cpu_shadow_cr0);
- printk("guest CR3 = %llx\n", vmcb->cr3);
-#endif
- printk("%s: pt = %lx\n", __func__, pt);
-}
-
-
-void svm_dump_host_regs(const char *from)
-{
- struct vcpu *v = current;
- unsigned long pt = pt = pagetable_get_paddr(v->arch.monitor_table);
- unsigned long cr3, cr0;
- printk("Host registers at %s\n", from);
-
- __asm__ __volatile__ ("\tmov %%cr0,%0\n"
- "\tmov %%cr3,%1\n"
- : "=r" (cr0), "=r"(cr3));
- printk("%s: pt = %lx, cr3 = %lx, cr0 = %lx\n", __func__, pt, cr3, cr0);
-}
-
-#ifdef SVM_EXTRA_DEBUG
-static char *exit_reasons[] = {
- [VMEXIT_CR0_READ] = "CR0_READ",
- [VMEXIT_CR1_READ] = "CR1_READ",
- [VMEXIT_CR2_READ] = "CR2_READ",
- [VMEXIT_CR3_READ] = "CR3_READ",
- [VMEXIT_CR4_READ] = "CR4_READ",
- [VMEXIT_CR5_READ] = "CR5_READ",
- [VMEXIT_CR6_READ] = "CR6_READ",
- [VMEXIT_CR7_READ] = "CR7_READ",
- [VMEXIT_CR8_READ] = "CR8_READ",
- [VMEXIT_CR9_READ] = "CR9_READ",
- [VMEXIT_CR10_READ] = "CR10_READ",
- [VMEXIT_CR11_READ] = "CR11_READ",
- [VMEXIT_CR12_READ] = "CR12_READ",
- [VMEXIT_CR13_READ] = "CR13_READ",
- [VMEXIT_CR14_READ] = "CR14_READ",
- [VMEXIT_CR15_READ] = "CR15_READ",
- [VMEXIT_CR0_WRITE] = "CR0_WRITE",
- [VMEXIT_CR1_WRITE] = "CR1_WRITE",
- [VMEXIT_CR2_WRITE] = "CR2_WRITE",
- [VMEXIT_CR3_WRITE] = "CR3_WRITE",
- [VMEXIT_CR4_WRITE] = "CR4_WRITE",
- [VMEXIT_CR5_WRITE] = "CR5_WRITE",
- [VMEXIT_CR6_WRITE] = "CR6_WRITE",
- [VMEXIT_CR7_WRITE] = "CR7_WRITE",
- [VMEXIT_CR8_WRITE] = "CR8_WRITE",
- [VMEXIT_CR9_WRITE] = "CR9_WRITE",
- [VMEXIT_CR10_WRITE] = "CR10_WRITE",
- [VMEXIT_CR11_WRITE] = "CR11_WRITE",
- [VMEXIT_CR12_WRITE] = "CR12_WRITE",
- [VMEXIT_CR13_WRITE] = "CR13_WRITE",
- [VMEXIT_CR14_WRITE] = "CR14_WRITE",
- [VMEXIT_CR15_WRITE] = "CR15_WRITE",
- [VMEXIT_DR0_READ] = "DR0_READ",
- [VMEXIT_DR1_READ] = "DR1_READ",
- [VMEXIT_DR2_READ] = "DR2_READ",
- [VMEXIT_DR3_READ] = "DR3_READ",
- [VMEXIT_DR4_READ] = "DR4_READ",
- [VMEXIT_DR5_READ] = "DR5_READ",
- [VMEXIT_DR6_READ] = "DR6_READ",
- [VMEXIT_DR7_READ] = "DR7_READ",
- [VMEXIT_DR8_READ] = "DR8_READ",
- [VMEXIT_DR9_READ] = "DR9_READ",
- [VMEXIT_DR10_READ] = "DR10_READ",
- [VMEXIT_DR11_READ] = "DR11_READ",
- [VMEXIT_DR12_READ] = "DR12_READ",
- [VMEXIT_DR13_READ] = "DR13_READ",
- [VMEXIT_DR14_READ] = "DR14_READ",
- [VMEXIT_DR15_READ] = "DR15_READ",
- [VMEXIT_DR0_WRITE] = "DR0_WRITE",
- [VMEXIT_DR1_WRITE] = "DR1_WRITE",
- [VMEXIT_DR2_WRITE] = "DR2_WRITE",
- [VMEXIT_DR3_WRITE] = "DR3_WRITE",
- [VMEXIT_DR4_WRITE] = "DR4_WRITE",
- [VMEXIT_DR5_WRITE] = "DR5_WRITE",
- [VMEXIT_DR6_WRITE] = "DR6_WRITE",
- [VMEXIT_DR7_WRITE] = "DR7_WRITE",
- [VMEXIT_DR8_WRITE] = "DR8_WRITE",
- [VMEXIT_DR9_WRITE] = "DR9_WRITE",
- [VMEXIT_DR10_WRITE] = "DR10_WRITE",
- [VMEXIT_DR11_WRITE] = "DR11_WRITE",
- [VMEXIT_DR12_WRITE] = "DR12_WRITE",
- [VMEXIT_DR13_WRITE] = "DR13_WRITE",
- [VMEXIT_DR14_WRITE] = "DR14_WRITE",
- [VMEXIT_DR15_WRITE] = "DR15_WRITE",
- [VMEXIT_EXCEPTION_DE] = "EXCEPTION_DE",
- [VMEXIT_EXCEPTION_DB] = "EXCEPTION_DB",
- [VMEXIT_EXCEPTION_NMI] = "EXCEPTION_NMI",
- [VMEXIT_EXCEPTION_BP] = "EXCEPTION_BP",
- [VMEXIT_EXCEPTION_OF] = "EXCEPTION_OF",
- [VMEXIT_EXCEPTION_BR] = "EXCEPTION_BR",
- [VMEXIT_EXCEPTION_UD] = "EXCEPTION_UD",
- [VMEXIT_EXCEPTION_NM] = "EXCEPTION_NM",
- [VMEXIT_EXCEPTION_DF] = "EXCEPTION_DF",
- [VMEXIT_EXCEPTION_09] = "EXCEPTION_09",
- [VMEXIT_EXCEPTION_TS] = "EXCEPTION_TS",
- [VMEXIT_EXCEPTION_NP] = "EXCEPTION_NP",
- [VMEXIT_EXCEPTION_SS] = "EXCEPTION_SS",
- [VMEXIT_EXCEPTION_GP] = "EXCEPTION_GP",
- [VMEXIT_EXCEPTION_PF] = "EXCEPTION_PF",
- [VMEXIT_EXCEPTION_15] = "EXCEPTION_15",
- [VMEXIT_EXCEPTION_MF] = "EXCEPTION_MF",
- [VMEXIT_EXCEPTION_AC] = "EXCEPTION_AC",
- [VMEXIT_EXCEPTION_MC] = "EXCEPTION_MC",
- [VMEXIT_EXCEPTION_XF] = "EXCEPTION_XF",
- [VMEXIT_INTR] = "INTR",
- [VMEXIT_NMI] = "NMI",
- [VMEXIT_SMI] = "SMI",
- [VMEXIT_INIT] = "INIT",
- [VMEXIT_VINTR] = "VINTR",
- [VMEXIT_CR0_SEL_WRITE] = "CR0_SEL_WRITE",
- [VMEXIT_IDTR_READ] = "IDTR_READ",
- [VMEXIT_GDTR_READ] = "GDTR_READ",
- [VMEXIT_LDTR_READ] = "LDTR_READ",
- [VMEXIT_TR_READ] = "TR_READ",
- [VMEXIT_IDTR_WRITE] = "IDTR_WRITE",
- [VMEXIT_GDTR_WRITE] = "GDTR_WRITE",
- [VMEXIT_LDTR_WRITE] = "LDTR_WRITE",
- [VMEXIT_TR_WRITE] = "TR_WRITE",
- [VMEXIT_RDTSC] = "RDTSC",
- [VMEXIT_RDPMC] = "RDPMC",
- [VMEXIT_PUSHF] = "PUSHF",
- [VMEXIT_POPF] = "POPF",
- [VMEXIT_CPUID] = "CPUID",
- [VMEXIT_RSM] = "RSM",
- [VMEXIT_IRET] = "IRET",
- [VMEXIT_SWINT] = "SWINT",
- [VMEXIT_INVD] = "INVD",
- [VMEXIT_PAUSE] = "PAUSE",
- [VMEXIT_HLT] = "HLT",
- [VMEXIT_INVLPG] = "INVLPG",
- [VMEXIT_INVLPGA] = "INVLPGA",
- [VMEXIT_IOIO] = "IOIO",
- [VMEXIT_MSR] = "MSR",
- [VMEXIT_TASK_SWITCH] = "TASK_SWITCH",
- [VMEXIT_FERR_FREEZE] = "FERR_FREEZE",
- [VMEXIT_SHUTDOWN] = "SHUTDOWN",
- [VMEXIT_VMRUN] = "VMRUN",
- [VMEXIT_VMMCALL] = "VMMCALL",
- [VMEXIT_VMLOAD] = "VMLOAD",
- [VMEXIT_VMSAVE] = "VMSAVE",
- [VMEXIT_STGI] = "STGI",
- [VMEXIT_CLGI] = "CLGI",
- [VMEXIT_SKINIT] = "SKINIT",
- [VMEXIT_RDTSCP] = "RDTSCP",
- [VMEXIT_ICEBP] = "ICEBP",
- [VMEXIT_NPF] = "NPF"
-};
-#endif /* SVM_EXTRA_DEBUG */
-
-#ifdef SVM_WALK_GUEST_PAGES
-void walk_shadow_and_guest_pt(unsigned long gva)
-{
- l2_pgentry_t gpde;
- l2_pgentry_t spde;
- l1_pgentry_t gpte;
- l1_pgentry_t spte;
- struct vcpu *v = current;
- struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
- paddr_t gpa;
-
- gpa = paging_gva_to_gpa(current, gva);
- printk("gva = %lx, gpa=%"PRIpaddr", gCR3=%x\n", gva, gpa, (u32)vmcb->cr3);
- if( !svm_paging_enabled(v) || mmio_space(gpa) )
- return;
-
- /* let's dump the guest and shadow page info */
-
- __guest_get_l2e(v, gva, &gpde);
- printk( "G-PDE = %x, flags=%x\n", gpde.l2, l2e_get_flags(gpde) );
- __shadow_get_l2e( v, gva, &spde );
- printk( "S-PDE = %x, flags=%x\n", spde.l2, l2e_get_flags(spde) );
-
- if ( unlikely(!(l2e_get_flags(gpde) & _PAGE_PRESENT)) )
- return;
-
- spte = l1e_empty();
-
- /* This is actually overkill - we only need to ensure the hl2 is in-sync.*/
- shadow_sync_va(v, gva);
-
- gpte.l1 = 0;
- __copy_from_user(&gpte, &__linear_l1_table[ l1_linear_offset(gva) ],
- sizeof(gpte) );
- printk( "G-PTE = %x, flags=%x\n", gpte.l1, l1e_get_flags(gpte) );
-
- BUG(); // need to think about this, and convert usage of
- // phys_to_machine_mapping to use pagetable format...
- __copy_from_user( &spte, &phys_to_machine_mapping[ l1e_get_pfn( gpte ) ],
- sizeof(spte) );
-
- printk( "S-PTE = %x, flags=%x\n", spte.l1, l1e_get_flags(spte));
-}
-#endif /* SVM_WALK_GUEST_PAGES */
-
-
asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs)
{
unsigned int exit_reason;
unsigned long eip;
struct vcpu *v = current;
- int do_debug = 0;
- struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-
- ASSERT(vmcb);
+ struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
+ int inst_len;
exit_reason = vmcb->exitcode;
save_svm_cpu_user_regs(v, regs);
HVMTRACE_2D(VMEXIT, v, vmcb->rip, exit_reason);
- if (exit_reason == VMEXIT_INVALID)
+ if ( unlikely(exit_reason == VMEXIT_INVALID) )
{
svm_dump_vmcb(__func__, vmcb);
goto exit_and_crash;
}
-#ifdef SVM_EXTRA_DEBUG
- {
-#if defined(__i386__)
-#define rip eip
-#endif
-
- static unsigned long intercepts_counter = 0;
-
- if (svm_dbg_on && exit_reason == VMEXIT_EXCEPTION_PF)
- {
- if (svm_paging_enabled(v) &&
- !mmio_space(
- paging_gva_to_gfn(current, vmcb->exitinfo2) << PAGE_SHIFT))
- {
- printk("I%08ld,ExC=%s(%d),IP=%x:%"PRIx64","
- "I1=%"PRIx64",I2=%"PRIx64",INT=%"PRIx64", "
- "gpa=%"PRIx64"\n", intercepts_counter,
- exit_reasons[exit_reason], exit_reason, regs->cs,
- (u64)regs->rip,
- (u64)vmcb->exitinfo1,
- (u64)vmcb->exitinfo2,
- (u64)vmcb->exitintinfo.bytes,
- (((u64)paging_gva_to_gfn(current, vmcb->exitinfo2)
- << PAGE_SHIFT) | (vmcb->exitinfo2 & ~PAGE_MASK)));
- }
- else
- {
- printk("I%08ld,ExC=%s(%d),IP=%x:%"PRIx64","
- "I1=%"PRIx64",I2=%"PRIx64",INT=%"PRIx64"\n",
- intercepts_counter,
- exit_reasons[exit_reason], exit_reason, regs->cs,
- (u64)regs->rip,
- (u64)vmcb->exitinfo1,
- (u64)vmcb->exitinfo2,
- (u64)vmcb->exitintinfo.bytes );
- }
- }
- else if ( svm_dbg_on
- && exit_reason != VMEXIT_IOIO
- && exit_reason != VMEXIT_INTR)
- {
-
- if (exit_reasons[exit_reason])
- {
- printk("I%08ld,ExC=%s(%d),IP=%x:%"PRIx64","
- "I1=%"PRIx64",I2=%"PRIx64",INT=%"PRIx64"\n",
- intercepts_counter,
- exit_reasons[exit_reason], exit_reason, regs->cs,
- (u64)regs->rip,
- (u64)vmcb->exitinfo1,
- (u64)vmcb->exitinfo2,
- (u64)vmcb->exitintinfo.bytes);
- }
- else
- {
- printk("I%08ld,ExC=%d(0x%x),IP=%x:%"PRIx64","
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|