[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Merge with PPC Xen tree.
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Date 1184664021 -3600 # Node ID 9559ba7c80f9b4a262e54f780d8fed71e8d23b88 # Parent c9720159b98323a45e1a91c00fee01c680f5d754 # Parent 23dab4b0545531e0ea0476b486c89a42455bcbe1 Merge with PPC Xen tree. --- xen/arch/ia64/vmx/vmx_process.c | 503 ------ .hgignore | 8 Config.mk | 8 docs/xen-api/xenapi-datamodel-graph.dot | 4 docs/xen-api/xenapi-datamodel.tex | 824 ++++++++++ extras/mini-os/arch/ia64/ia64.S | 7 extras/mini-os/arch/ia64/ivt.S | 49 extras/mini-os/include/ia64/ia64_cpu.h | 4 tools/firmware/hvmloader/acpi/dsdt.asl | 21 tools/firmware/hvmloader/acpi/dsdt.c | 25 tools/firmware/hvmloader/config.h | 2 tools/firmware/hvmloader/hvmloader.c | 12 tools/firmware/rombios/rombios.c | 48 tools/ioemu/hw/ide.c | 3 tools/ioemu/hw/rtl8139.c | 11 tools/ioemu/target-i386-dm/exec-dm.c | 6 tools/ioemu/target-i386-dm/helper2.c | 1 tools/ioemu/vl.c | 5 tools/ioemu/vl.h | 9 tools/libxc/ia64/xc_dom_ia64_util.c | 2 tools/libxc/ia64/xc_ia64_hvm_build.c | 21 tools/libxc/xc_domain.c | 33 tools/libxc/xc_linux.c | 2 tools/libxc/xc_ptrace.c | 10 tools/libxc/xenctrl.h | 26 tools/libxen/include/xen/api/xen_acmpolicy.h | 117 + tools/libxen/include/xen/api/xen_vdi.h | 13 tools/libxen/include/xen/api/xen_vm.h | 14 tools/libxen/include/xen/api/xen_xspolicy.h | 271 +++ tools/libxen/include/xen/api/xen_xspolicy_decl.h | 31 tools/libxen/src/xen_acmpolicy.c | 234 ++ tools/libxen/src/xen_vdi.c | 39 tools/libxen/src/xen_vm.c | 45 tools/libxen/src/xen_xspolicy.c | 327 +++ tools/python/xen/util/acmpolicy.py | 81 tools/python/xen/util/security.py | 69 tools/python/xen/xend/XendConfig.py | 2 tools/python/xen/xend/XendDomain.py | 8 tools/python/xen/xend/XendDomainInfo.py | 2 tools/python/xen/xm/activatepolicy.py | 86 + tools/python/xen/xm/addlabel.py | 135 + tools/python/xen/xm/cfgbootpolicy.py | 76 tools/python/xen/xm/create.dtd | 7 tools/python/xen/xm/create.py | 22 tools/python/xen/xm/getlabel.py | 45 tools/python/xen/xm/getpolicy.py | 94 + tools/python/xen/xm/labels.py | 37 tools/python/xen/xm/loadpolicy.py | 32 tools/python/xen/xm/main.py | 88 - tools/python/xen/xm/makepolicy.py | 14 tools/python/xen/xm/resources.py | 33 tools/python/xen/xm/rmlabel.py | 65 tools/python/xen/xm/setpolicy.py | 117 + tools/python/xen/xm/xenapi_create.py | 55 tools/security/policies/security_policy.xsd | 7 tools/vtpm_manager/util/hashtable_itr.c | 8 tools/xenstore/xsls.c | 37 tools/xentrace/xenctx.c | 364 +++- unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h | 9 unmodified_drivers/linux-2.6/netfront/Kbuild | 1 xen/Makefile | 16 xen/arch/ia64/Makefile | 2 xen/arch/ia64/Rules.mk | 2 xen/arch/ia64/linux-xen/efi.c | 5 xen/arch/ia64/linux-xen/perfmon.c | 2 xen/arch/ia64/linux-xen/sn/kernel/irq.c | 15 xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c | 101 + xen/arch/ia64/vmx/Makefile | 2 xen/arch/ia64/vmx/mmio.c | 15 xen/arch/ia64/vmx/vmmu.c | 3 xen/arch/ia64/vmx/vmx_fault.c | 524 ++++++ xen/arch/ia64/vmx/vmx_init.c | 6 xen/arch/ia64/vmx/vmx_ivt.S | 2 xen/arch/ia64/vmx/vmx_minstate.h | 4 xen/arch/ia64/vmx/vmx_utility.c | 13 xen/arch/ia64/vmx/vmx_vcpu.c | 3 xen/arch/ia64/vmx/vmx_virt.c | 45 xen/arch/ia64/xen/Makefile | 1 xen/arch/ia64/xen/dom0_ops.c | 51 xen/arch/ia64/xen/dom_fw_sn2.c | 92 + xen/arch/ia64/xen/dom_fw_utils.c | 35 xen/arch/ia64/xen/domain.c | 111 + xen/arch/ia64/xen/faults.c | 41 xen/arch/ia64/xen/fw_emul.c | 150 + xen/arch/ia64/xen/hypercall.c | 10 xen/arch/ia64/xen/hyperprivop.S | 48 xen/arch/ia64/xen/ivt.S | 66 xen/arch/ia64/xen/mm.c | 23 xen/arch/ia64/xen/oprofile/perfmon.c | 11 xen/arch/ia64/xen/oprofile/xenoprof.c | 26 xen/arch/ia64/xen/privop.c | 2 xen/arch/ia64/xen/vcpu.c | 86 - xen/arch/ia64/xen/vhpt.c | 2 xen/arch/ia64/xen/xenasm.S | 3 xen/arch/ia64/xen/xenmisc.c | 19 xen/arch/ia64/xen/xenpatch.c | 7 xen/arch/ia64/xen/xensetup.c | 31 xen/arch/ia64/xen/xentime.c | 8 xen/arch/x86/acpi/Makefile | 1 xen/arch/x86/acpi/power.c | 274 +++ xen/arch/x86/acpi/suspend.c | 85 + xen/arch/x86/acpi/wakeup_prot.S | 267 +++ xen/arch/x86/apic.c | 2 xen/arch/x86/boot/Makefile | 3 xen/arch/x86/boot/head.S | 2 xen/arch/x86/boot/wakeup.S | 212 ++ xen/arch/x86/cpu/common.c | 11 xen/arch/x86/crash.c | 4 xen/arch/x86/dmi_scan.c | 1 xen/arch/x86/domain.c | 19 xen/arch/x86/domain_build.c | 3 xen/arch/x86/domctl.c | 40 xen/arch/x86/hvm/hvm.c | 6 xen/arch/x86/hvm/svm/svm.c | 10 xen/arch/x86/hvm/svm/vmcb.c | 10 xen/arch/x86/hvm/vlapic.c | 9 xen/arch/x86/hvm/vmx/vmcs.c | 219 +- xen/arch/x86/hvm/vmx/vmx.c | 96 - xen/arch/x86/i8259.c | 6 xen/arch/x86/io_apic.c | 3 xen/arch/x86/irq.c | 33 xen/arch/x86/machine_kexec.c | 4 xen/arch/x86/mm.c | 23 xen/arch/x86/mm/hap/hap.c | 122 - xen/arch/x86/mm/hap/support.c | 164 + xen/arch/x86/nmi.c | 2 xen/arch/x86/oprofile/nmi_int.c | 83 - xen/arch/x86/platform_hypercall.c | 17 xen/arch/x86/setup.c | 4 xen/arch/x86/shutdown.c | 2 xen/arch/x86/smp.c | 2 xen/arch/x86/smpboot.c | 340 +++- xen/arch/x86/x86_32/traps.c | 2 xen/arch/x86/x86_64/mm.c | 3 xen/arch/x86/x86_64/traps.c | 2 xen/common/grant_table.c | 12 xen/common/page_alloc.c | 58 xen/common/sysctl.c | 14 xen/common/xenoprof.c | 52 xen/drivers/char/ns16550.c | 4 xen/drivers/char/serial.c | 4 xen/include/acm/acm_core.h | 4 xen/include/asm-ia64/config.h | 6 xen/include/asm-ia64/debugger.h | 45 xen/include/asm-ia64/dom_fw_common.h | 1 xen/include/asm-ia64/domain.h | 45 xen/include/asm-ia64/linux-xen/asm/machvec.h | 69 xen/include/asm-ia64/linux-xen/asm/machvec_sn2.h | 7 xen/include/asm-ia64/linux-xen/asm/processor.h | 4 xen/include/asm-ia64/linux-xen/asm/ptrace.h | 42 xen/include/asm-ia64/vcpu.h | 13 xen/include/asm-ia64/vmmu.h | 1 xen/include/asm-ia64/vmx.h | 2 xen/include/asm-ia64/vmx_vcpu.h | 32 xen/include/asm-ia64/xenkregs.h | 15 xen/include/asm-ia64/xenoprof.h | 2 xen/include/asm-x86/acpi.h | 8 xen/include/asm-x86/config.h | 10 xen/include/asm-x86/desc.h | 5 xen/include/asm-x86/hap.h | 3 xen/include/asm-x86/hvm/hvm.h | 21 xen/include/asm-x86/hvm/support.h | 1 xen/include/asm-x86/hvm/vmx/vmcs.h | 9 xen/include/asm-x86/page.h | 15 xen/include/asm-x86/processor.h | 18 xen/include/asm-x86/smp.h | 13 xen/include/asm-x86/system.h | 2 xen/include/asm-x86/xenoprof.h | 4 xen/include/public/arch-ia64.h | 135 - xen/include/public/foreign/reference.size | 6 xen/include/public/platform.h | 27 xen/include/public/sysctl.h | 13 xen/include/xen/cpumask.h | 2 xen/include/xen/irq.h | 10 xen/include/xen/mm.h | 5 xen/include/xen/xenoprof.h | 2 176 files changed, 6619 insertions(+), 2020 deletions(-) diff -r c9720159b983 -r 9559ba7c80f9 .hgignore --- a/.hgignore Mon Jul 16 14:20:16 2007 -0500 +++ b/.hgignore Tue Jul 17 10:20:21 2007 +0100 @@ -130,6 +130,8 @@ ^tools/ioemu/qemu\.1$ ^tools/ioemu/qemu\.pod$ ^tools/libxc/xen/.*$ +^tools/libxc/ia64/asm/acpi\.h$ +^tools/libxc/ia64/xen/list\.h$ ^tools/libxen/libxenapi- ^tools/libxen/test/test_bindings$ ^tools/libxen/test/test_event_handling$ @@ -211,6 +213,7 @@ ^tools/xm-test/lib/XmTestReport/xmtest.py$ ^tools/xm-test/tests/.*\.test$ ^xen/BLOG$ +^xen/System.map$ ^xen/TAGS$ ^xen/arch/x86/asm-offsets\.s$ ^xen/arch/x86/boot/mkelf32$ @@ -218,6 +221,7 @@ ^xen/ddb/.*$ ^xen/include/asm$ ^xen/include/asm-.*/asm-offsets\.h$ +^xen/include/asm-ia64/asm-xsi-offsets\.h$ ^xen/include/compat/.*$ ^xen/include/hypervisor-ifs/arch$ ^xen/include/public/foreign/.*\.(c|h|size)$ @@ -233,6 +237,10 @@ ^xen/xen$ ^xen/xen-syms$ ^xen/xen\..*$ +^xen/arch/ia64/asm-offsets\.s$ +^xen/arch/ia64/asm-xsi-offsets\.s$ +^xen/arch/ia64/map\.out$ +^xen/arch/ia64/xen\.lds\.s$ ^xen/arch/powerpc/dom0\.bin$ ^xen/arch/powerpc/asm-offsets\.s$ ^xen/arch/powerpc/firmware$ diff -r c9720159b983 -r 9559ba7c80f9 Config.mk --- a/Config.mk Mon Jul 16 14:20:16 2007 -0500 +++ b/Config.mk Tue Jul 17 10:20:21 2007 +0100 @@ -81,14 +81,6 @@ CFLAGS += $(foreach i, $(EXTRA_INCLUDES) # n - Do not build the Xen ACM framework ACM_SECURITY ?= n -# If ACM_SECURITY = y and no boot policy file is installed, -# then the ACM defaults to the security policy set by -# ACM_DEFAULT_SECURITY_POLICY -# Supported models are: -# ACM_NULL_POLICY -# ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY -ACM_DEFAULT_SECURITY_POLICY ?= ACM_NULL_POLICY - # Optional components XENSTAT_XENTOP ?= y VTPM_TOOLS ?= n diff -r c9720159b983 -r 9559ba7c80f9 docs/xen-api/xenapi-datamodel-graph.dot --- a/docs/xen-api/xenapi-datamodel-graph.dot Mon Jul 16 14:20:16 2007 -0500 +++ b/docs/xen-api/xenapi-datamodel-graph.dot Tue Jul 17 10:20:21 2007 +0100 @@ -12,7 +12,7 @@ digraph "Xen-API Class Diagram" { digraph "Xen-API Class Diagram" { fontname="Verdana"; -node [ shape=box ]; session VM host network VIF PIF SR VDI VBD PBD user; +node [ shape=box ]; session VM host network VIF PIF SR VDI VBD PBD user XSPolicy ACMPolicy; node [shape=ellipse]; PIF_metrics VIF_metrics VM_metrics VBD_metrics PBD_metrics VM_guest_metrics host_metrics; node [shape=box]; host_cpu console session -> host [ arrowhead="none" ] @@ -36,4 +36,6 @@ VBD -> VM [ arrowhead="none", arrowtail= VBD -> VM [ arrowhead="none", arrowtail="crow" ] VTPM -> VM [ arrowhead="none", arrowtail="crow" ] VBD -> VBD_metrics [ arrowhead="none" ] +XSPolicy -> host [ arrowhead="none" ] +XSPolicy -> ACMPolicy [ arrowhead="none" ] } diff -r c9720159b983 -r 9559ba7c80f9 docs/xen-api/xenapi-datamodel.tex --- a/docs/xen-api/xenapi-datamodel.tex Mon Jul 16 14:20:16 2007 -0500 +++ b/docs/xen-api/xenapi-datamodel.tex Tue Jul 17 10:20:21 2007 +0100 @@ -46,6 +46,8 @@ Name & Description \\ {\tt console} & A console \\ {\tt user} & A user of the system \\ {\tt debug} & A basic class for testing \\ +{\tt XSPolicy} & A class for handling Xen Security Policies \\ +{\tt ACMPolicy} & A class for handling ACM-type policies \\ \hline \end{tabular}\end{center} \section{Relationships Between Classes} @@ -226,6 +228,7 @@ The following enumeration types are used \vspace{1cm} \newpage + \section{Error Handling} When a low-level transport error occurs, or a request is malformed at the HTTP or XML-RPC level, the server may send an XML-RPC Fault response, or the client @@ -468,6 +471,17 @@ HVM is required for this operation {\bf Signature:} \begin{verbatim}VM_HVM_REQUIRED(vm)\end{verbatim} \begin{center}\rule{10em}{0.1pt}\end{center} + +\subsubsection{SECURITY\_ERROR} + +A security error occurred. The parameter provides the xen security +error code and a message describing the error. + +\vspace{0.3cm} +{\bf Signature:} +\begin{verbatim}SECURITY_ERROR(xserr, message)\end{verbatim} +\begin{center}\rule{10em}{0.1pt}\end{center} + \newpage \section{Class: session} @@ -1401,6 +1415,7 @@ Quals & Field & Type & Description \\ $\mathit{RO}_\mathit{run}$ & {\tt is\_control\_domain} & bool & true if this is a control domain (domain 0 or a driver domain) \\ $\mathit{RO}_\mathit{run}$ & {\tt metrics} & VM\_metrics ref & metrics associated with this VM \\ $\mathit{RO}_\mathit{run}$ & {\tt guest\_metrics} & VM\_guest\_metrics ref & metrics associated with the running guest \\ +$\mathit{RO}_\mathit{run}$ & {\tt security/label} & string & the VM's security label \\ \hline \end{longtable} \subsection{RPCs associated with class: VM} @@ -4395,6 +4410,82 @@ VM\_guest\_metrics ref value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_security\_label} + +{\bf Overview:} +Get the security label field of the given VM. Refer to the XSPolicy class +for the format of the security label. + + \noindent {\bf Signature:} +\begin{verbatim} string get_security_label (session_id s, VM 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 VM ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +string +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~set\_security\_label} + +{\bf Overview:} +Set the security label field of the given VM. Refer to the XSPolicy class +for the format of the security label. + + \noindent {\bf Signature:} +\begin{verbatim} int set_security_label (session_id s, VM ref self, string +security_label, string old_label)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VM ref } & self & reference to the object \\ \hline +{\tt string } & security\_label & security label for the VM \\ \hline +{\tt string } & old\_label & Optional label value that the security label \\ +& & must currently have for the change to succeed.\\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +int +} + + +Returns the ssidref in case of an VM that is currently running or +paused, zero in case of a dormant VM (halted, suspended). + +\vspace{0.3cm} + +\noindent{\bf Possible Error Codes:} {\tt SECURITY\_ERROR} + \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} @@ -11317,6 +11408,79 @@ void \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} +\subsubsection{RPC name:~set\_security\_label} + +{\bf Overview:} +Set the security label of the given VDI. Refer to the XSPolicy class +for the format of the security label. + + \noindent {\bf Signature:} +\begin{verbatim} void set_security_label (session_id s, VDI ref self, string +security_label, string old_label)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt VDI ref } & self & reference to the object \\ \hline + +{\tt string } & security\_label & New value of the security label \\ \hline +{\tt string } & old\_label & Optional label value that the security label \\ +& & must currently have for the change to succeed.\\ \hline +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +void +} + + +\vspace{0.3cm} + +\noindent{\bf Possible Error Codes:} {\tt SECURITY\_ERROR} + +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_security\_label} + +{\bf Overview:} +Get the security label of the given VDI. + + \noindent {\bf Signature:} +\begin{verbatim} string get_security_label (session_id s, VDI 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 VDI ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +string +} + + +value of the given field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} \subsubsection{RPC name:~create} {\bf Overview:} @@ -13424,6 +13588,38 @@ value of the field \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} +\subsubsection{RPC name:~get\_runtime\_properties} + +{\bf Overview:} +Get the runtime\_properties field of the given VTPM. + +\noindent {\bf Signature:} +\begin{verbatim} ((string -> string) Map) get_runtime_properties (session_id s, VTPM 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 VTPM 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:~create} {\bf Overview:} @@ -14268,6 +14464,634 @@ all fields from the object \vspace{0.3cm} \vspace{1cm} +\newpage +\section{Class: XSPolicy} +\subsection{Fields for class: XSPolicy} +\begin{longtable}{|lllp{0.38\textwidth}|} +\hline +\multicolumn{1}{|l}{Name} & \multicolumn{3}{l|}{\bf XSPolicy} \\ +\multicolumn{1}{|l}{Description} & \multicolumn{3}{l|}{\parbox{11cm}{\em A Xen Security Policy}} \\ +\hline +Quals & Field & Type & Description \\ +\hline +$\mathit{RO}_\mathit{run}$ & {\tt uuid} & string & unique identifier / object reference \\ +$\mathit{RW}$ & {\tt repr} & string & representation of policy, i.e., XML \\ +$\mathit{RO}_\mathit{run}$ & {\tt type} & xs\_type & type of the policy \\ +$\mathit{RO}_\mathit{run}$ & {\tt flags} & xs\_instantiationflags & policy +status flags \\ +\hline +\end{longtable} +\subsection{Semantics of the class: XSPolicy} + +The XSPolicy class is used for administering Xen Security policies. Through +this class a new policy can be uploaded to the system, loaded into the +Xen hypervisor for enforcement and be set as the policy that the +system is automatically loading when the machine is started. + +This class returns information about the currently administered policy, +including a reference to the policy. This reference can then be used with +policy-specific classes, i.e., the ACMPolicy class, to allow retrieval of +information or changes to be made to a particular policy. + +\subsection{Structure and datatypes of class: XSPolicy} + +Format of the security label: + +A security label consist of the three different parts {\it policy type}, +{\it policy name} and {\it label} separated with colons. To specify +the virtual machine label for an ACM-type policy {\it xm-test}, the +security label string would be {\it ACM:xm-test:blue}, where blue +denotes the virtual machine's label. The format of resource labels is +the same.\\[0.5cm] +The following flags are used by this class: + +\begin{longtable}{|l|l|l|} +\hline +{\tt xs\_type} & value & meaning \\ +\hline +\hspace{0.5cm}{\tt XS\_POLICY\_ACM} & (1 $<<$ 0) & ACM-type policy \\ +\hline +\end{longtable} + +\begin{longtable}{|l|l|l|} +\hline +{\tt xs\_instantiationflags} & value & meaning \\ +\hline +\hspace{0.5cm}{\tt XS\_INST\_NONE} & 0 & do nothing \\ +\hspace{0.5cm}{\tt XS\_INST\_BOOT} & (1 $<<$ 0) & make system boot with this policy \\ +\hspace{0.5cm}{\tt XS\_INST\_LOAD} & (1 $<<$ 1) & load policy immediately \\ +\hline +\end{longtable} + +\begin{longtable}{|l|l|l|} +\hline +{\tt xs\_policystate} & type & meaning \\ +\hline +\hspace{0.5cm}{\tt xserr} & int & Error code from operation (if applicable) \\ +\hspace{0.5cm}{\tt xs\_ref} & XSPolicy ref & reference to the XS policy as returned by the API \\ +\hspace{0.5cm}{\tt repr} & string & representation of the policy, i.e., XML \\ +\hspace{0.5cm}{\tt type} & xs\_type & the type of the policy \\ +\hspace{0.5cm}{\tt flags } & xs\_instantiationflags & instantiation flags of the policy \\ +\hspace{0.5cm}{\tt version} & string & version of the policy \\ +\hspace{0.5cm}{\tt errors} & string & Base64-encoded sequence of integer tuples consisting \\ +& & of (error code, detail); will be returned as part \\ +& & of the xs\_setpolicy function. \\ +\hline +\end{longtable} + +\subsection{Additional RPCs associated with class: XSPolicy} +\subsubsection{RPC name:~get\_xstype} + +{\bf Overview:} +Return the Xen Security Policy types supported by this system + + \noindent {\bf Signature:} +\begin{verbatim} xs_type get_xstype (session_id s)\end{verbatim} + + \noindent {\bf Return Type:} +{\tt +xs\_type +} + +flags representing the supported Xen security policy types + \vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~set\_xspolicy} + +{\bf Overview:} +Set the current XSPolicy. This function can also be be used for updating of +an existing policy whose name must be equivalent to the one of the +currently running policy. + +\noindent {\bf Signature:} +\begin{verbatim} xs_policystate set_xspolicy (session_id s, xs_type type, string repr, +xs_instantiationflags flags, bool overwrite)\end{verbatim} + +\noindent{\bf Arguments:} + +\vspace{0.3cm} + +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt xs\_type } & type & the type of policy \\ \hline +{\tt string} & repr & representation of the policy, i.e., XML \\ \hline +{\tt xs\_instantiationflags} & flags & flags for the setting of the policy \\ \hline +{\tt bool} & overwrite & whether to overwrite an existing policy \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + + \noindent {\bf Return Type:} +{\tt +xs\_policystate +} + + +State information about the policy. In case an error occurred, the 'xs\_err' +field contains the error code. The 'errors' may contain further information +about the error. +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_xspolicy} + +{\bf Overview:} +Get information regarding the currently set Xen Security Policy + + \noindent {\bf Signature:} +\begin{verbatim} xs_policystate get_xspolicy (session_id s)\end{verbatim} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +xs\_policystate +} + + +Policy state information. +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~rm\_xsbootpolicy} + +{\bf Overview:} +Remove any policy from the default boot configuration. + + \noindent {\bf Signature:} +\begin{verbatim} void rm_xsbootpolicy (session_id s)\end{verbatim} + +\vspace{0.3cm} + +\noindent{\bf Possible Error Codes:} {\tt SECURITY\_ERROR} + +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_labeled\_resources} + +{\bf Overview:} +Get a list of resources that have been labeled. + + \noindent {\bf Signature:} +\begin{verbatim} ((string -> string) Map) get_labeled_resources (session_id s)\end{verbatim} + + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(string $\rightarrow$ string) Map +} + + +A map of resources with their labels. +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~set\_resource\_label} + +{\bf Overview:} +Label the given resource with the given label. An empty label removes any label +from the resource. + + \noindent {\bf Signature:} +\begin{verbatim} void set_resource_label (session_id s, string resource, string +label, string old_label)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt string } & resource & resource to label \\ \hline +{\tt string } & label & label for the resource \\ \hline +{\tt string } & old\_label & Optional label value that the security label \\ +& & must currently have for the change to succeed. \\ \hline + +\end{tabular} + +\vspace{0.3cm} + +\noindent{\bf Possible Error Codes:} {\tt SECURITY\_ERROR} + +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_resource\_label} + +{\bf Overview:} +Get the label of the given resource. + + \noindent {\bf Signature:} +\begin{verbatim} string get_resource_label (session_id s, string resource)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt string } & resource & resource to label \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +string +} + + +The label of the given resource. +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~activate\_xspolicy} + +{\bf Overview:} +Load the referenced policy into the hypervisor. + + \noindent {\bf Signature:} +\begin{verbatim} xs_instantiationflags activate_xspolicy (session_id s, xs_ref xspolicy, +xs_instantiationflags flags)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt xs ref } & self & reference to the object \\ \hline +{\tt xs\_instantiationflags } & flags & flags to activate on a policy; flags + can only be set \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + + \noindent {\bf Return Type:} +{\tt +xs\_instantiationflags +} + + +Currently active instantiation flags. +\vspace{0.3cm} + +\noindent{\bf Possible Error Codes:} {\tt SECURITY\_ERROR} + +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_all} + +{\bf Overview:} +Return a list of all the XSPolicies known to the system. + + \noindent {\bf Signature:} +\begin{verbatim} ((XSPolicy ref) Set) get_all (session_id s)\end{verbatim} + + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(XSPolicy ref) Set +} + + +A list of all the IDs of all the XSPolicies +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_uuid} + +{\bf Overview:} +Get the uuid field of the given XSPolicy. + + \noindent {\bf Signature:} +\begin{verbatim} string get_uuid (session_id s, XSPolicy 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 XSPolicy ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +string +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_record} + +{\bf Overview:} +Get a record of the referenced XSPolicy. + + \noindent {\bf Signature:} +\begin{verbatim} (XSPolicy record) get_record (session_id s, xs_ref xspolicy)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt xs ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +XSPolicy record +} + + +all fields from the object +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\newpage +\section{Class: ACMPolicy} +\subsection{Fields for class: ACMPolicy} +\begin{longtable}{|lllp{0.38\textwidth}|} +\hline +\multicolumn{1}{|l}{Name} & \multicolumn{3}{l|}{\bf ACMPolicy} \\ +\multicolumn{1}{|l}{Description} & \multicolumn{3}{l|}{\parbox{11cm}{\em An ACM Security Policy}} \\ +\hline +Quals & Field & Type & Description \\ +\hline +$\mathit{RO}_\mathit{run}$ & {\tt uuid} & string & unique identifier / object reference \\ +$\mathit{RW}$ & {\tt repr} & string & representation of policy, in XML \\ +$\mathit{RO}_\mathit{run}$ & {\tt type} & xs\_type & type of the policy \\ +$\mathit{RO}_\mathit{run}$ & {\tt flags} & xs\_instantiationflags & policy +status flags \\ +\hline +\end{longtable} + +\subsection{Structure and datatypes of class: ACMPolicy} + +\vspace{0.5cm} +The following data structures are used: + +\begin{longtable}{|l|l|l|} +\hline +{\tt RIP acm\_policyheader} & type & meaning \\ +\hline +\hspace{0.5cm}{\tt policyname} & string & name of the policy \\ +\hspace{0.5cm}{\tt policyurl } & string & URL of the policy \\ +\hspace{0.5cm}{\tt date} & string & data of the policy \\ +\hspace{0.5cm}{\tt reference} & string & reference of the policy \\ +\hspace{0.5cm}{\tt namespaceurl} & string & namespaceurl of the policy \\ +\hspace{0.5cm}{\tt version} & string & version of the policy \\ +\hline +\end{longtable} + +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_header} + +{\bf Overview:} +Get the referenced policy's header information. + + \noindent {\bf Signature:} +\begin{verbatim} acm_policyheader get_header (session_id s, xs 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 xs ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +acm\_policyheader +} + + +The policy's header information. +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_xml} + +{\bf Overview:} +Get the XML representation of the given policy. + + \noindent {\bf Signature:} +\begin{verbatim} string get_XML (session_id s, xs 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 xs ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +string +} + + +XML representation of the referenced policy +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_map} + +{\bf Overview:} +Get the mapping information of the given policy. + + \noindent {\bf Signature:} +\begin{verbatim} string get_map (session_id s, xs 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 xs ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +string +} + + +Mapping information of the referenced policy. +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_binary} + +{\bf Overview:} +Get the binary policy representation of the referenced policy. + + \noindent {\bf Signature:} +\begin{verbatim} string get_map (session_id s, xs 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 xs ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +string +} + + +Base64-encoded representation of the binary policy. +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_all} + +{\bf Overview:} +Return a list of all the ACMPolicies known to the system. + + \noindent {\bf Signature:} +\begin{verbatim} ((ACMPolicy ref) Set) get_all (session_id s)\end{verbatim} + + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +(ACMPolicy ref) Set +} + + +A list of all the IDs of all the ACMPolicies +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_uuid} + +{\bf Overview:} +Get the uuid field of the given ACMPolicy. + + \noindent {\bf Signature:} +\begin{verbatim} string get_uuid (session_id s, ACMPolicy 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 ACMPolicy ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +string +} + + +value of the field +\vspace{0.3cm} +\vspace{0.3cm} +\vspace{0.3cm} +\subsubsection{RPC name:~get\_record} + +{\bf Overview:} +Get a record of the referenced ACMPolicy. + + \noindent {\bf Signature:} +\begin{verbatim} (XSPolicy record) get_record (session_id s, xs_ref xspolicy)\end{verbatim} + + +\noindent{\bf Arguments:} + + +\vspace{0.3cm} +\begin{tabular}{|c|c|p{7cm}|} + \hline +{\bf type} & {\bf name} & {\bf description} \\ \hline +{\tt xs ref } & self & reference to the object \\ \hline + +\end{tabular} + +\vspace{0.3cm} + + \noindent {\bf Return Type:} +{\tt +XSPolicy record +} + + +all fields from the object + \newpage \section{Class: debug} \subsection{Fields for class: debug} diff -r c9720159b983 -r 9559ba7c80f9 extras/mini-os/arch/ia64/ia64.S --- a/extras/mini-os/arch/ia64/ia64.S Mon Jul 16 14:20:16 2007 -0500 +++ b/extras/mini-os/arch/ia64/ia64.S Tue Jul 17 10:20:21 2007 +0100 @@ -105,7 +105,7 @@ ENTRY(_start) /* * Now pin mappings into the TLB for kernel text and data */ - mov r18=KERNEL_TR_PAGE_SIZE<<2 + mov r18=KERNEL_TR_PAGE_SIZE<<IA64_ITIR_PS movl r17=KERNEL_START ;; mov cr.itir=r18 @@ -204,7 +204,10 @@ 1: /* now we are in virtual mode */ ;; or out0=r16, r15 // make a region 7 address ;; - + ssm psr.i | psr.ic + ;; + srlz.i + ;; br.call.sptk.many rp=start_kernel ;; add r2=3,r0 diff -r c9720159b983 -r 9559ba7c80f9 extras/mini-os/arch/ia64/ivt.S --- a/extras/mini-os/arch/ia64/ivt.S Mon Jul 16 14:20:16 2007 -0500 +++ b/extras/mini-os/arch/ia64/ivt.S Tue Jul 17 10:20:21 2007 +0100 @@ -587,13 +587,11 @@ END(save_special_regs) ENTRY(hypervisor_callback) - // Calculate the stack address for storing. - // Use the kernel stack here because it's mapped wired! - // -> no nested tlb faults! - movl r18=kstack+KSTACK_PAGES * PAGE_SIZE - 16 - TF_SIZE - - //add r18=-TF_SIZE,sp - add r30=0xabab,r0 + /* + * Use the thread stack here for storing the trap frame. + * It's not wired mapped, so nested data tlb faults may occur! + */ + add r18=-TF_SIZE,sp ;; { .mib nop 0x02 @@ -602,7 +600,7 @@ ENTRY(hypervisor_callback) ;; } add sp=-16,r18 // the new stack - alloc r15=ar.pfs,0,0,1,0 // 1 out for do_trap_error + alloc r15=ar.pfs,0,0,1,0 // 1 out for do_hypervisor_callback ;; mov out0=r18 // the trap frame movl r22=XSI_PSR_IC @@ -617,13 +615,8 @@ ENTRY(hypervisor_callback) movl r22=XSI_PSR_IC ;; st4 [r22]=r0 // rsm psr.ic - - add r16=16,sp // load EF-pointer again - ;; - //mov r18=sp - movl r18=kstack+KSTACK_PAGES * PAGE_SIZE - 16 - TF_SIZE - ;; - + add r18=16,sp // load EF-pointer again + ;; // must have r18-efp, calls rfi at the end. br.sptk restore_tf_rse_switch ;; @@ -654,9 +647,7 @@ ENTRY(trap_error) mov out0=r18 // the trap frame add sp=-16,r18 // C-call abi ;; - - //bsw.1 - movl r30=XSI_BANKNUM + movl r30=XSI_BANKNUM // bsw.1 mov r31=1;; #if defined(BIG_ENDIAN) // swap because mini-os is in BE mux1 r31=r31,@rev;; @@ -752,6 +743,7 @@ IVT_ERR(Alternate_Instruction_TLB, 3, 0x IVT_ENTRY(Alternate_Data_TLB, 0x1000) mov r30=4 // trap number +adt_common: mov r16=cr.ifa // where did it happen mov r31=pr // save predicates ;; @@ -765,7 +757,7 @@ IVT_ENTRY(Alternate_Data_TLB, 0x1000) // // No return // //adt_regf_addr: -// extr.u r17=r16,60,4 // get region number +// extr.u r17=r16,60,4 // get region number // ;; // cmp.eq p14,p15=0xf,r17 // ;; @@ -799,8 +791,23 @@ adt_reg7_addr: IVT_END(Alternate_Data_TLB) - -IVT_ERR(Data_Nested_TLB, 5, 0x1400) +/* + * Handling of nested data tlb is needed, because in hypervisor_callback() + * the stack is used to store the register trap frame. This stack is allocated + * dynamically (as identity mapped address) and therewidth no tr mapped page! + */ +IVT_ENTRY(Data_Nested_TLB, 0x1400) + + mov r30=5 // trap number + add r28=-TF_SIZE,sp // r28 is never used in trap handling + ;; + mov cr.ifa=r28 + ;; + br.sptk adt_common +IVT_END(Data_Nested_TLB) + + + IVT_ERR(Instruction_Key_Miss, 6, 0x1800) IVT_ERR(Data_Key_Miss, 7, 0x1c00) IVT_ERR(Dirty_Bit, 8, 0x2000) diff -r c9720159b983 -r 9559ba7c80f9 extras/mini-os/include/ia64/ia64_cpu.h --- a/extras/mini-os/include/ia64/ia64_cpu.h Mon Jul 16 14:20:16 2007 -0500 +++ b/extras/mini-os/include/ia64/ia64_cpu.h Tue Jul 17 10:20:21 2007 +0100 @@ -143,11 +143,11 @@ #define STARTUP_PSR (IA64_PSR_IT | \ IA64_PSR_DT | IA64_PSR_RT | MOS_IA64_PSR_BE | \ - IA64_PSR_BN | IA64_PSR_CPL_2 | IA64_PSR_AC) + IA64_PSR_BN | IA64_PSR_CPL_KERN | IA64_PSR_AC) #define MOS_SYS_PSR (IA64_PSR_IC | IA64_PSR_I | IA64_PSR_IT | \ IA64_PSR_DT | IA64_PSR_RT | MOS_IA64_PSR_BE | \ - IA64_PSR_BN | IA64_PSR_CPL_2 | IA64_PSR_AC) + IA64_PSR_BN | IA64_PSR_CPL_KERN | IA64_PSR_AC) #define MOS_USR_PSR (IA64_PSR_IC | IA64_PSR_I | IA64_PSR_IT | \ IA64_PSR_DT | IA64_PSR_RT | MOS_IA64_PSR_BE | \ diff -r c9720159b983 -r 9559ba7c80f9 tools/firmware/hvmloader/acpi/dsdt.asl --- a/tools/firmware/hvmloader/acpi/dsdt.asl Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/firmware/hvmloader/acpi/dsdt.asl Tue Jul 17 10:20:21 2007 +0100 @@ -123,11 +123,12 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, } Name(BUFA, ResourceTemplate() { - IRQ(Level, ActiveLow, Shared) { 5, 7, 10, 11 } + IRQ(Level, ActiveLow, Shared) { 5, 10, 11 } }) Name(BUFB, Buffer() { - 0x23, 0x00, 0x00, 0x18, 0x79, 0 + 0x23, 0x00, 0x00, 0x18, /* IRQ descriptor */ + 0x79, 0 /* End tag, null checksum */ }) CreateWordField(BUFB, 0x01, IRQV) @@ -643,6 +644,22 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, IRQNoFlags () {4} }) } + + Device (LTP1) + { + Name (_HID, EisaId ("PNP0400")) + Name (_UID, 0x02) + Method (_STA, 0, NotSerialized) + { + Return (0x0F) + } + + Name (_CRS, ResourceTemplate() + { + IO (Decode16, 0x0378, 0x0378, 0x08, 0x08) + IRQNoFlags () {7} + }) + } } } } diff -r c9720159b983 -r 9559ba7c80f9 tools/firmware/hvmloader/acpi/dsdt.c --- a/tools/firmware/hvmloader/acpi/dsdt.c Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/firmware/hvmloader/acpi/dsdt.c Tue Jul 17 10:20:21 2007 +0100 @@ -1,19 +1,19 @@ /* * * Intel ACPI Component Architecture - * ASL Optimizing Compiler version 20060707 [Dec 30 2006] + * ASL Optimizing Compiler version 20060707 [Feb 16 2007] * Copyright (C) 2000 - 2006 Intel Corporation * Supports ACPI Specification Revision 3.0a * - * Compilation of "dsdt.asl" - Sat May 12 16:13:55 2007 + * Compilation of "dsdt.asl" - Wed Jul 11 13:34:30 2007 * * C source code output * */ unsigned char AmlCode[] = { - 0x44,0x53,0x44,0x54,0x67,0x0D,0x00,0x00, /* 00000000 "DSDTg..." */ - 0x02,0xE0,0x58,0x65,0x6E,0x00,0x00,0x00, /* 00000008 "..Xen..." */ + 0x44,0x53,0x44,0x54,0x9F,0x0D,0x00,0x00, /* 00000000 "DSDT...." */ + 0x02,0x2E,0x58,0x65,0x6E,0x00,0x00,0x00, /* 00000008 "..Xen..." */ 0x48,0x56,0x4D,0x00,0x00,0x00,0x00,0x00, /* 00000010 "HVM....." */ 0x00,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */ 0x07,0x07,0x06,0x20,0x08,0x50,0x4D,0x42, /* 00000020 "... .PMB" */ @@ -27,7 +27,7 @@ unsigned char AmlCode[] = 0x04,0x0A,0x07,0x0A,0x07,0x00,0x00,0x08, /* 00000060 "........" */ 0x50,0x49,0x43,0x44,0x00,0x14,0x0C,0x5F, /* 00000068 "PICD..._" */ 0x50,0x49,0x43,0x01,0x70,0x68,0x50,0x49, /* 00000070 "PIC.phPI" */ - 0x43,0x44,0x10,0x4C,0xCE,0x5F,0x53,0x42, /* 00000078 "CD.L._SB" */ + 0x43,0x44,0x10,0x44,0xD2,0x5F,0x53,0x42, /* 00000078 "CD.D._SB" */ 0x5F,0x5B,0x82,0x49,0x04,0x4D,0x45,0x4D, /* 00000080 "_[.I.MEM" */ 0x30,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41, /* 00000088 "0._HID.A" */ 0xD0,0x0C,0x02,0x08,0x5F,0x43,0x52,0x53, /* 00000090 "...._CRS" */ @@ -37,7 +37,7 @@ unsigned char AmlCode[] = 0x00,0x00,0xFF,0xFF,0x09,0x00,0x00,0x00, /* 000000B0 "........" */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000B8 "........" */ 0x00,0x00,0x00,0x00,0x0A,0x00,0x00,0x00, /* 000000C0 "........" */ - 0x00,0x00,0x79,0x00,0x5B,0x82,0x49,0xC9, /* 000000C8 "..y.[.I." */ + 0x00,0x00,0x79,0x00,0x5B,0x82,0x41,0xCD, /* 000000C8 "..y.[.A." */ 0x50,0x43,0x49,0x30,0x08,0x5F,0x48,0x49, /* 000000D0 "PCI0._HI" */ 0x44,0x0C,0x41,0xD0,0x0A,0x03,0x08,0x5F, /* 000000D8 "D.A...._" */ 0x55,0x49,0x44,0x00,0x08,0x5F,0x41,0x44, /* 000000E0 "UID.._AD" */ @@ -59,7 +59,7 @@ unsigned char AmlCode[] = 0x00,0xF0,0xFF,0xFF,0xFF,0xF4,0x00,0x00, /* 00000160 "........" */ 0x00,0x00,0x00,0x00,0x00,0x05,0x79,0x00, /* 00000168 "......y." */ 0xA4,0x50,0x52,0x54,0x30,0x08,0x42,0x55, /* 00000170 ".PRT0.BU" */ - 0x46,0x41,0x11,0x09,0x0A,0x06,0x23,0xA0, /* 00000178 "FA....#." */ + 0x46,0x41,0x11,0x09,0x0A,0x06,0x23,0x20, /* 00000178 "FA....# " */ 0x0C,0x18,0x79,0x00,0x08,0x42,0x55,0x46, /* 00000180 "..y..BUF" */ 0x42,0x11,0x09,0x0A,0x06,0x23,0x00,0x00, /* 00000188 "B....#.." */ 0x18,0x79,0x00,0x8B,0x42,0x55,0x46,0x42, /* 00000190 ".y..BUFB" */ @@ -348,7 +348,7 @@ unsigned char AmlCode[] = 0x0C,0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A, /* 00000A68 "........" */ 0x02,0x00,0x0A,0x2F,0x12,0x0C,0x04,0x0C, /* 00000A70 ".../...." */ 0xFF,0xFF,0x0F,0x00,0x0A,0x03,0x00,0x0A, /* 00000A78 "........" */ - 0x10,0x5B,0x82,0x44,0x2E,0x49,0x53,0x41, /* 00000A80 ".[.D.ISA" */ + 0x10,0x5B,0x82,0x4C,0x31,0x49,0x53,0x41, /* 00000A80 ".[.L1ISA" */ 0x5F,0x08,0x5F,0x41,0x44,0x52,0x0C,0x00, /* 00000A88 "_._ADR.." */ 0x00,0x01,0x00,0x5B,0x80,0x50,0x49,0x52, /* 00000A90 "...[.PIR" */ 0x51,0x02,0x0A,0x60,0x0A,0x04,0x10,0x2E, /* 00000A98 "Q..`...." */ @@ -440,6 +440,13 @@ unsigned char AmlCode[] = 0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A, /* 00000D48 "._STA..." */ 0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x10, /* 00000D50 ".._CRS.." */ 0x0A,0x0D,0x47,0x01,0xF8,0x03,0xF8,0x03, /* 00000D58 "..G....." */ - 0x01,0x08,0x22,0x10,0x00,0x79,0x00, + 0x01,0x08,0x22,0x10,0x00,0x79,0x00,0x5B, /* 00000D60 ".."..y.[" */ + 0x82,0x36,0x4C,0x54,0x50,0x31,0x08,0x5F, /* 00000D68 ".6LTP1._" */ + 0x48,0x49,0x44,0x0C,0x41,0xD0,0x04,0x00, /* 00000D70 "HID.A..." */ + 0x08,0x5F,0x55,0x49,0x44,0x0A,0x02,0x14, /* 00000D78 "._UID..." */ + 0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A, /* 00000D80 "._STA..." */ + 0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x10, /* 00000D88 ".._CRS.." */ + 0x0A,0x0D,0x47,0x01,0x78,0x03,0x78,0x03, /* 00000D90 "..G.x.x." */ + 0x08,0x08,0x22,0x80,0x00,0x79,0x00, }; int DsdtLen=sizeof(AmlCode); diff -r c9720159b983 -r 9559ba7c80f9 tools/firmware/hvmloader/config.h --- a/tools/firmware/hvmloader/config.h Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/firmware/hvmloader/config.h Tue Jul 17 10:20:21 2007 +0100 @@ -9,7 +9,7 @@ #define LAPIC_ID(vcpu_id) ((vcpu_id) * 2) #define PCI_ISA_DEVFN 0x08 /* dev 1, fn 0 */ -#define PCI_ISA_IRQ_MASK 0x0ca0U /* ISA IRQs 5,7,10,11 are PCI connected */ +#define PCI_ISA_IRQ_MASK 0x0c20U /* ISA IRQs 5,10,11 are PCI connected */ #define ROMBIOS_SEG 0xF000 #define ROMBIOS_BEGIN 0x000F0000 diff -r c9720159b983 -r 9559ba7c80f9 tools/firmware/hvmloader/hvmloader.c --- a/tools/firmware/hvmloader/hvmloader.c Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/firmware/hvmloader/hvmloader.c Tue Jul 17 10:20:21 2007 +0100 @@ -180,15 +180,13 @@ static void pci_setup(void) unsigned int bar, pin, link, isa_irq; /* Program PCI-ISA bridge with appropriate link routes. */ - link = 0; - for ( isa_irq = 0; isa_irq < 15; isa_irq++ ) - { - if ( !(PCI_ISA_IRQ_MASK & (1U << isa_irq)) ) - continue; + isa_irq = 0; + for ( link = 0; link < 4; link++ ) + { + do { isa_irq = (isa_irq + 1) & 15; + } while ( !(PCI_ISA_IRQ_MASK & (1U << isa_irq)) ); pci_writeb(PCI_ISA_DEVFN, 0x60 + link, isa_irq); printf("PCI-ISA link %u routed to IRQ%u\n", link, isa_irq); - if ( link++ == 4 ) - break; } /* Program ELCR to match PCI-wired IRQs. */ diff -r c9720159b983 -r 9559ba7c80f9 tools/firmware/rombios/rombios.c --- a/tools/firmware/rombios/rombios.c Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/firmware/rombios/rombios.c Tue Jul 17 10:20:21 2007 +0100 @@ -9146,78 +9146,78 @@ pci_routing_table_structure: db 0 ;; pci bus number db 0x08 ;; pci device number (bit 7-3) db 0x61 ;; link value INTA#: pointer into PCI2ISA config space - dw 0x0ca0 ;; IRQ bitmap INTA# + dw 0x0c20 ;; IRQ bitmap INTA# db 0x62 ;; link value INTB# - dw 0x0ca0 ;; IRQ bitmap INTB# + dw 0x0c20 ;; IRQ bitmap INTB# db 0x63 ;; link value INTC# - dw 0x0ca0 ;; IRQ bitmap INTC# + dw 0x0c20 ;; IRQ bitmap INTC# db 0x60 ;; link value INTD# - dw 0x0ca0 ;; IRQ bitmap INTD# + dw 0x0c20 ;; IRQ bitmap INTD# db 0 ;; physical slot (0 = embedded) db 0 ;; reserved ;; second slot entry: 1st PCI slot db 0 ;; pci bus number db 0x10 ;; pci device number (bit 7-3) db 0x62 ;; link value INTA# - dw 0x0ca0 ;; IRQ bitmap INTA# + dw 0x0c20 ;; IRQ bitmap INTA# db 0x63 ;; link value INTB# - dw 0x0ca0 ;; IRQ bitmap INTB# + dw 0x0c20 ;; IRQ bitmap INTB# db 0x60 ;; link value INTC# - dw 0x0ca0 ;; IRQ bitmap INTC# + dw 0x0c20 ;; IRQ bitmap INTC# db 0x61 ;; link value INTD# - dw 0x0ca0 ;; IRQ bitmap INTD# + dw 0x0c20 ;; IRQ bitmap INTD# db 1 ;; physical slot (0 = embedded) db 0 ;; reserved ;; third slot entry: 2nd PCI slot db 0 ;; pci bus number db 0x18 ;; pci device number (bit 7-3) db 0x63 ;; link value INTA# - dw 0x0ca0 ;; IRQ bitmap INTA# + dw 0x0c20 ;; IRQ bitmap INTA# db 0x60 ;; link value INTB# - dw 0x0ca0 ;; IRQ bitmap INTB# + dw 0x0c20 ;; IRQ bitmap INTB# db 0x61 ;; link value INTC# - dw 0x0ca0 ;; IRQ bitmap INTC# + dw 0x0c20 ;; IRQ bitmap INTC# db 0x62 ;; link value INTD# - dw 0x0ca0 ;; IRQ bitmap INTD# + dw 0x0c20 ;; IRQ bitmap INTD# db 2 ;; physical slot (0 = embedded) db 0 ;; reserved ;; 4th slot entry: 3rd PCI slot db 0 ;; pci bus number db 0x20 ;; pci device number (bit 7-3) db 0x60 ;; link value INTA# - dw 0x0ca0 ;; IRQ bitmap INTA# + dw 0x0c20 ;; IRQ bitmap INTA# db 0x61 ;; link value INTB# - dw 0x0ca0 ;; IRQ bitmap INTB# + dw 0x0c20 ;; IRQ bitmap INTB# db 0x62 ;; link value INTC# - dw 0x0ca0 ;; IRQ bitmap INTC# + dw 0x0c20 ;; IRQ bitmap INTC# db 0x63 ;; link value INTD# - dw 0x0ca0 ;; IRQ bitmap INTD# + dw 0x0c20 ;; IRQ bitmap INTD# db 3 ;; physical slot (0 = embedded) db 0 ;; reserved ;; 5th slot entry: 4rd PCI slot db 0 ;; pci bus number db 0x28 ;; pci device number (bit 7-3) db 0x61 ;; link value INTA# - dw 0x0ca0 ;; IRQ bitmap INTA# + dw 0x0c20 ;; IRQ bitmap INTA# db 0x62 ;; link value INTB# - dw 0x0ca0 ;; IRQ bitmap INTB# + dw 0x0c20 ;; IRQ bitmap INTB# db 0x63 ;; link value INTC# - dw 0x0ca0 ;; IRQ bitmap INTC# + dw 0x0c20 ;; IRQ bitmap INTC# db 0x60 ;; link value INTD# - dw 0x0ca0 ;; IRQ bitmap INTD# + dw 0x0c20 ;; IRQ bitmap INTD# db 4 ;; physical slot (0 = embedded) db 0 ;; reserved ;; 6th slot entry: 5rd PCI slot db 0 ;; pci bus number db 0x30 ;; pci device number (bit 7-3) db 0x62 ;; link value INTA# - dw 0x0ca0 ;; IRQ bitmap INTA# + dw 0x0c20 ;; IRQ bitmap INTA# db 0x63 ;; link value INTB# - dw 0x0ca0 ;; IRQ bitmap INTB# + dw 0x0c20 ;; IRQ bitmap INTB# db 0x60 ;; link value INTC# - dw 0x0ca0 ;; IRQ bitmap INTC# + dw 0x0c20 ;; IRQ bitmap INTC# db 0x61 ;; link value INTD# - dw 0x0ca0 ;; IRQ bitmap INTD# + dw 0x0c20 ;; IRQ bitmap INTD# db 5 ;; physical slot (0 = embedded) db 0 ;; reserved #endif // BX_PCIBIOS diff -r c9720159b983 -r 9559ba7c80f9 tools/ioemu/hw/ide.c --- a/tools/ioemu/hw/ide.c Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/ioemu/hw/ide.c Tue Jul 17 10:20:21 2007 +0100 @@ -596,7 +596,8 @@ static void ide_identify(IDEState *s) /* 13=flush_cache_ext,12=flush_cache,10=lba48 */ put_le16(p + 83, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10)); put_le16(p + 84, (1 << 14)); - put_le16(p + 85, (1 << 14)); + /* 14=nop 5=write_cache */ + put_le16(p + 85, (1 << 14) | (1 << 5)); /* 13=flush_cache_ext,12=flush_cache,10=lba48 */ put_le16(p + 86, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10)); put_le16(p + 87, (1 << 14)); diff -r c9720159b983 -r 9559ba7c80f9 tools/ioemu/hw/rtl8139.c --- a/tools/ioemu/hw/rtl8139.c Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/ioemu/hw/rtl8139.c Tue Jul 17 10:20:21 2007 +0100 @@ -53,9 +53,8 @@ /* debug RTL8139 card C+ mode only */ //#define DEBUG_RTL8139CP 1 -/* RTL8139 provides frame CRC with received packet, this feature seems to be - ignored by most drivers, disabled by default */ -//#define RTL8139_CALCULATE_RXCRC 1 +/* Calculate CRCs propoerly on Rx packets */ +#define RTL8139_CALCULATE_RXCRC 1 /* Uncomment to enable on-board timer interrupts */ //#define RTL8139_ONBOARD_TIMER 1 @@ -754,7 +753,7 @@ static void rtl8139_write_buffer(RTL8139 int wrapped = MOD2(s->RxBufAddr + size, s->RxBufferSize); /* write packet data */ - if (wrapped && s->RxBufferSize < 65536 && !rtl8139_RxWrap(s)) + if (wrapped && !(s->RxBufferSize < 65536 && rtl8139_RxWrap(s))) { DEBUG_PRINT((">>> RTL8139: rx packet wrapped in buffer at %d\n", size-wrapped)); @@ -1030,7 +1029,7 @@ static void rtl8139_do_receive(void *opa /* write checksum */ #if defined (RTL8139_CALCULATE_RXCRC) - val = cpu_to_le32(crc32(~0, buf, size)); + val = cpu_to_le32(crc32(0, buf, size)); #else val = 0; #endif @@ -1136,7 +1135,7 @@ static void rtl8139_do_receive(void *opa /* write checksum */ #if defined (RTL8139_CALCULATE_RXCRC) - val = cpu_to_le32(crc32(~0, buf, size)); + val = cpu_to_le32(crc32(0, buf, size)); #else val = 0; #endif diff -r c9720159b983 -r 9559ba7c80f9 tools/ioemu/target-i386-dm/exec-dm.c --- a/tools/ioemu/target-i386-dm/exec-dm.c Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/ioemu/target-i386-dm/exec-dm.c Tue Jul 17 10:20:21 2007 +0100 @@ -446,18 +446,16 @@ extern unsigned long logdirty_bitmap_siz #if defined(__x86_64__) || defined(__i386__) static void memcpy_words(void *dst, void *src, size_t n) { - asm ( + asm volatile ( " movl %%edx,%%ecx \n" #ifdef __x86_64__ " shrl $3,%%ecx \n" - " andl $7,%%edx \n" " rep movsq \n" " test $4,%%edx \n" " jz 1f \n" " movsl \n" #else /* __i386__ */ " shrl $2,%%ecx \n" - " andl $3,%%edx \n" " rep movsl \n" #endif "1: test $2,%%edx \n" @@ -467,7 +465,7 @@ static void memcpy_words(void *dst, void " jz 1f \n" " movsb \n" "1: \n" - : : "S" (src), "D" (dst), "d" (n) : "ecx" ); + : "+S" (src), "+D" (dst) : "d" (n) : "ecx", "memory" ); } #else static void memcpy_words(void *dst, void *src, size_t n) diff -r c9720159b983 -r 9559ba7c80f9 tools/ioemu/target-i386-dm/helper2.c --- a/tools/ioemu/target-i386-dm/helper2.c Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/ioemu/target-i386-dm/helper2.c Tue Jul 17 10:20:21 2007 +0100 @@ -140,6 +140,7 @@ void cpu_reset(CPUX86State *env) if (xcHandle < 0) fprintf(logfile, "Cannot acquire xenctrl handle\n"); else { + xc_domain_shutdown_hook(xcHandle, domid); sts = xc_domain_shutdown(xcHandle, domid, SHUTDOWN_reboot); if (sts != 0) fprintf(logfile, diff -r c9720159b983 -r 9559ba7c80f9 tools/ioemu/vl.c --- a/tools/ioemu/vl.c Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/ioemu/vl.c Tue Jul 17 10:20:21 2007 +0100 @@ -7141,13 +7141,8 @@ int main(int argc, char **argv) serial_devices[i][0] = '\0'; serial_device_index = 0; -#ifndef CONFIG_DM pstrcpy(parallel_devices[0], sizeof(parallel_devices[0]), "vc"); for(i = 1; i < MAX_PARALLEL_PORTS; i++) -#else - /* Xen steals IRQ7 for PCI. Disable LPT1 by default. */ - for(i = 0; i < MAX_PARALLEL_PORTS; i++) -#endif parallel_devices[i][0] = '\0'; parallel_device_index = 0; diff -r c9720159b983 -r 9559ba7c80f9 tools/ioemu/vl.h --- a/tools/ioemu/vl.h Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/ioemu/vl.h Tue Jul 17 10:20:21 2007 +0100 @@ -1498,4 +1498,13 @@ void destroy_hvm_domain(void); /* VNC Authentication */ #define AUTHCHALLENGESIZE 16 +#ifdef __ia64__ +static inline void xc_domain_shutdown_hook(int xc_handle, uint32_t domid) +{ + xc_ia64_save_to_nvram(xc_handle, domid); +} +#else +#define xc_domain_shutdown_hook(xc_handle, domid) do {} while (0) +#endif + #endif /* VL_H */ diff -r c9720159b983 -r 9559ba7c80f9 tools/libxc/ia64/xc_dom_ia64_util.c --- a/tools/libxc/ia64/xc_dom_ia64_util.c Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/libxc/ia64/xc_dom_ia64_util.c Tue Jul 17 10:20:21 2007 +0100 @@ -104,7 +104,7 @@ xen_ia64_is_vcpu_allocated(struct xc_dom if (rc == 0) return 1; - if (rc != -ESRCH) + if (errno != ESRCH) PERROR("Could not get vcpu info"); return 0; } diff -r c9720159b983 -r 9559ba7c80f9 tools/libxc/ia64/xc_ia64_hvm_build.c --- a/tools/libxc/ia64/xc_ia64_hvm_build.c Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/libxc/ia64/xc_ia64_hvm_build.c Tue Jul 17 10:20:21 2007 +0100 @@ -623,6 +623,21 @@ copy_from_nvram_to_GFW(int xc_handle, ui /* + *Check is the address where NVRAM data located valid + */ +static int is_valid_address(void *addr) +{ + struct nvram_save_addr *p = (struct nvram_save_addr *)addr; + + if ( p->signature == NVRAM_VALID_SIG ) + return 1; + else { + PERROR("Invalid nvram signature. Nvram save failed!\n"); + return 0; + } +} + +/* * GFW use 4k page. when doing foreign map, we should 16k align * the address and map one more page to guarantee all 64k nvram data * can be got. @@ -667,7 +682,11 @@ copy_from_GFW_to_nvram(int xc_handle, ui return -1; } - addr_from_GFW_4k_align = *((uint64_t *)tmp_ptr); + /* Check is NVRAM data vaild */ + if ( !is_valid_address(tmp_ptr) ) + return -1; + + addr_from_GFW_4k_align = ((struct nvram_save_addr *)tmp_ptr)->addr; munmap(tmp_ptr, PAGE_SIZE); // align address to 16k diff -r c9720159b983 -r 9559ba7c80f9 tools/libxc/xc_domain.c --- a/tools/libxc/xc_domain.c Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/libxc/xc_domain.c Tue Jul 17 10:20:21 2007 +0100 @@ -586,6 +586,27 @@ int xc_domain_ioport_permission(int xc_h domctl.u.ioport_permission.allow_access = allow_access; return do_domctl(xc_handle, &domctl); +} + +int xc_availheap(int xc_handle, + int min_width, + int max_width, + int node, + uint64_t *bytes) +{ + DECLARE_SYSCTL; + int rc; + + sysctl.cmd = XEN_SYSCTL_availheap; + sysctl.u.availheap.min_bitwidth = min_width; + sysctl.u.availheap.max_bitwidth = max_width; + sysctl.u.availheap.node = node; + + rc = xc_sysctl(xc_handle, &sysctl); + + *bytes = sysctl.u.availheap.avail_bytes; + + return rc; } int xc_vcpu_setcontext(int xc_handle, @@ -697,6 +718,18 @@ int xc_get_hvm_param(int handle, domid_t return rc; } +int xc_domain_setdebugging(int xc_handle, + uint32_t domid, + unsigned int enable) +{ + DECLARE_DOMCTL; + + domctl.cmd = XEN_DOMCTL_setdebugging; + domctl.domain = domid; + domctl.u.setdebugging.enable = enable; + return do_domctl(xc_handle, &domctl); +} + /* * Local variables: * mode: C diff -r c9720159b983 -r 9559ba7c80f9 tools/libxc/xc_linux.c --- a/tools/libxc/xc_linux.c Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/libxc/xc_linux.c Tue Jul 17 10:20:21 2007 +0100 @@ -456,7 +456,7 @@ void *xc_gnttab_map_grant_refs(int xcg_h map->count = count; - if ( ioctl(xcg_handle, IOCTL_GNTDEV_MAP_GRANT_REF, &map) ) + if ( ioctl(xcg_handle, IOCTL_GNTDEV_MAP_GRANT_REF, map) ) goto out; addr = mmap(NULL, PAGE_SIZE * count, prot, MAP_SHARED, xcg_handle, diff -r c9720159b983 -r 9559ba7c80f9 tools/libxc/xc_ptrace.c --- a/tools/libxc/xc_ptrace.c Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/libxc/xc_ptrace.c Tue Jul 17 10:20:21 2007 +0100 @@ -566,10 +566,7 @@ xc_ptrace( } if ( request == PTRACE_DETACH ) { - domctl.cmd = XEN_DOMCTL_setdebugging; - domctl.domain = current_domid; - domctl.u.setdebugging.enable = 0; - if ((retval = do_domctl(xc_handle, &domctl))) + if ((retval = xc_domain_setdebugging(xc_handle, current_domid, 0))) goto out_error_domctl; } regs_valid = 0; @@ -593,10 +590,7 @@ xc_ptrace( else if ((retval = xc_domain_pause(xc_handle, current_domid))) goto out_error_domctl; current_is_hvm = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_hvm_guest); - domctl.cmd = XEN_DOMCTL_setdebugging; - domctl.domain = current_domid; - domctl.u.setdebugging.enable = 1; - if ((retval = do_domctl(xc_handle, &domctl))) + if ((retval = xc_domain_setdebugging(xc_handle, current_domid, 1))) goto out_error_domctl; if (get_online_cpumap(xc_handle, &domctl.u.getdomaininfo, &cpumap)) diff -r c9720159b983 -r 9559ba7c80f9 tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/libxc/xenctrl.h Tue Jul 17 10:20:21 2007 +0100 @@ -433,6 +433,18 @@ int xc_domain_send_trigger(int xc_handle uint32_t trigger, uint32_t vcpu); +/** + * This function enables or disable debugging of a domain. + * + * @parm xc_handle a handle to an open hypervisor interface + * @parm domid the domain id to send trigger + * @parm enable true to enable debugging + * return 0 on success, -1 on failure + */ +int xc_domain_setdebugging(int xc_handle, + uint32_t domid, + unsigned int enable); + /* * EVENT CHANNEL FUNCTIONS */ @@ -616,6 +628,20 @@ int xc_get_pfn_type_batch(int xc_handle, /* Get current total pages allocated to a domain. */ long xc_get_tot_pages(int xc_handle, uint32_t domid); +/** + * This function retrieves the the number of bytes available + * in the heap in a specific range of address-widths and nodes. + * + * @parm xc_handle a handle to an open hypervisor interface + * @parm domid the domain to query + * @parm min_width the smallest address width to query (0 if don't care) + * @parm max_width the largest address width to query (0 if don't care) + * @parm node the node to query (-1 for all) + * @parm *bytes caller variable to put total bytes counted + * @return 0 on success, <0 on failure. + */ +int xc_availheap(int xc_handle, int min_width, int max_width, int node, + uint64_t *bytes); /* * Trace Buffer Operations diff -r c9720159b983 -r 9559ba7c80f9 tools/libxen/include/xen/api/xen_acmpolicy.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/libxen/include/xen/api/xen_acmpolicy.h Tue Jul 17 10:20:21 2007 +0100 @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2007, IBM Corp. + * Copyright (c) 2007, XenSource Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef XEN_ACMPOLICY_H +#define XEN_ACMPOLICY_H + +#include "xen_common.h" +#include "xen_string_string_map.h" +#include "xen_xspolicy_decl.h" +#include "xen_vm_decl.h" + +/* + * Data structures. + */ + +typedef struct xen_acmpolicy_record +{ + xen_xspolicy handle; + char *uuid; + char *repr; + xs_instantiationflags flags; + xs_type type; +} xen_acmpolicy_record; + +/** + * Allocate a xen_acmpolicy_record. + */ +extern xen_acmpolicy_record * +xen_acmpolicy_record_alloc(void); + +/** + * Free the given xen_xspolicy_record, and all referenced values. The + * given record must have been allocated by this library. + */ +extern void +xen_acmpolicy_record_free(xen_acmpolicy_record *record); + + +/** + * Data structures for the policy's header + */ +typedef struct xen_acm_header +{ + char *policyname; + char *policyurl; + char *date; + char *reference; + char *namespaceurl; + char *version; +} xen_acm_header; + +extern xen_acm_header * +xen_acm_header_alloc(void); + +extern void +xen_acm_header_free(xen_acm_header *hdr); + +/** + * Get the referenced policy's record. + */ +bool +xen_acmpolicy_get_record(xen_session *session, xen_acmpolicy_record **result, + xen_xspolicy xspolicy); + +/** + * Get the header of a policy. + */ +extern bool +xen_acmpolicy_get_header(xen_session *session, xen_acm_header **hdr, + xen_xspolicy xspolicy); + + +/** + * Get the XML representation of the policy. + */ +extern bool +xen_acmpolicy_get_xml(xen_session *session, char **xml, + xen_xspolicy xspolicy); + +/** + * Get the mapping file of the policy. + */ +extern bool +xen_acmpolicy_get_map(xen_session *session, char **map, + xen_xspolicy xspolicy); + +/** + * Get the binary representation (base64-encoded) of the policy. + */ +extern bool +xen_acmpolicy_get_binary(xen_session *session, char **binary, + xen_xspolicy xspolicy); + +/** + * Get the UUID filed of the given policy. + */ +bool +xen_acmpolicy_get_uuid(xen_session *session, char **result, + xen_xspolicy xspolicy); + +#endif diff -r c9720159b983 -r 9559ba7c80f9 tools/libxen/include/xen/api/xen_vdi.h --- a/tools/libxen/include/xen/api/xen_vdi.h Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/libxen/include/xen/api/xen_vdi.h Tue Jul 17 10:20:21 2007 +0100 @@ -344,4 +344,17 @@ xen_vdi_get_all(xen_session *session, st xen_vdi_get_all(xen_session *session, struct xen_vdi_set **result); +/** + * Set the security label of a VDI. + */ +extern bool +xen_vdi_set_security_label(xen_session *session, int64_t *result, xen_vdi vdi, + char *label, char *oldlabel); + +/** + * Get the security label of a VDI. + */ +extern bool +xen_vdi_get_security_label(xen_session *session, char **result, xen_vdi vdi); + #endif diff -r c9720159b983 -r 9559ba7c80f9 tools/libxen/include/xen/api/xen_vm.h --- a/tools/libxen/include/xen/api/xen_vm.h Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/libxen/include/xen/api/xen_vm.h Tue Jul 17 10:20:21 2007 +0100 @@ -112,6 +112,7 @@ typedef struct xen_vm_record bool is_control_domain; struct xen_vm_metrics_record_opt *metrics; struct xen_vm_guest_metrics_record_opt *guest_metrics; + char *security_label; } xen_vm_record; /** @@ -891,4 +892,17 @@ xen_vm_get_all(xen_session *session, str xen_vm_get_all(xen_session *session, struct xen_vm_set **result); +/** + * Set the security label of a domain. + */ +extern bool +xen_vm_set_security_label(xen_session *session, int64_t *result, xen_vm vm, + char *label, char *oldlabel); + +/** + * Get the security label of a domain. + */ +extern bool +xen_vm_get_security_label(xen_session *session, char **result, xen_vm vm); + #endif diff -r c9720159b983 -r 9559ba7c80f9 tools/libxen/include/xen/api/xen_xspolicy.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/libxen/include/xen/api/xen_xspolicy.h Tue Jul 17 10:20:21 2007 +0100 @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2007, IBM Corp. + * Copyright (c) 2007, XenSource Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef XEN_XSPOLICY_H +#define XEN_XSPOLICY_H + +#include "xen_common.h" +#include "xen_xspolicy_decl.h" +#include "xen_string_string_map.h" + + +/* + * The XSPolicy and associated data structures. + * + */ +typedef int64_t xs_type; +typedef int64_t xs_instantiationflags; + +enum xs_type { + XS_POLICY_ACM = (1 << 0), +}; + +enum xs_instantiationflags { + XS_INST_NONE = 0, + XS_INST_BOOT = (1 << 0), + XS_INST_LOAD = (1 << 1), +}; + + +/* Error codes returned by xend following XSPolicy operations */ +#define XSERR_BASE 0x1000 + +#define XSERR_SUCCESS 0 +#define XSERR_GENERAL_FAILURE 1 + XSERR_BASE +#define XSERR_BAD_XML 2 + XSERR_BASE +#define XSERR_XML_PROCESSING 3 + XSERR_BASE +#define XSERR_POLICY_INCONSISTENT 4 + XSERR_BASE +#define XSERR_FILE_ERROR 5 + XSERR_BASE +#define XSERR_BAD_RESOURCE_FORMAT 6 + XSERR_BASE +#define XSERR_BAD_LABEL_FORMAT 7 + XSERR_BASE +#define XSERR_RESOURCE_NOT_LABELED 8 + XSERR_BASE +#define XSERR_RESOURCE_ALREADY_LABELED 9 + XSERR_BASE +#define XSERR_WRONG_POLICY_TYPE 10 + XSERR_BASE +#define XSERR_BOOTPOLICY_INSTALLED 11 + XSERR_BASE +#define XSERR_NO_DEFAULT_BOOT_TITLE 12 + XSERR_BASE +#define XSERR_POLICY_LOAD_FAILED 13 + XSERR_BASE +#define XSERR_POLICY_LOADED 14 + XSERR_BASE +#define XSERR_POLICY_TYPE_UNSUPPORTED 15 + XSERR_BASE +#define XSERR_BAD_CONFLICTSET 20 + XSERR_BASE +#define XSERR_RESOURCE_IN_USE 21 + XSERR_BASE +#define XSERR_BAD_POLICY_NAME 22 + XSERR_BASE +#define XSERR_RESOURCE_ACCESS 23 + XSERR_BASE +#define XSERR_HV_OP_FAILED 24 + XSERR_BASE +#define XSERR_BOOTPOLICY_INSTALL_ERROR 25 + XSERR_BASE + + +/** + * Free the given xen_xspolicy. The given handle must have been allocated + * by this library. + */ +extern void +xen_xspolicy_free(xen_xspolicy xspolicy); + + +typedef struct xen_xspolicy_set +{ + size_t size; + xen_xspolicy *contents[]; +} xen_xspolicy_set; + +/** + * Allocate a xen_xspolicy_set of the given size. + */ +extern xen_xspolicy_set * +xen_xspolicy_set_alloc(size_t size); + +/** + * Free the given xen_xspolicy_set. The given set must have been allocated + * by this library. + */ +extern void +xen_xspolicy_set_free(xen_xspolicy_set *set); + + +typedef struct xen_xspolicy_record +{ + xen_xspolicy handle; + char *uuid; + char *repr; + xs_instantiationflags flags; + xs_type type; +} xen_xspolicy_record; + +/** + * Allocate a xen_xspolicy_record. + */ +extern xen_xspolicy_record * +xen_xspolicy_record_alloc(void); + +/** + * Free the given xen_xspolicy_record, and all referenced values. The + * given record must have been allocated by this library. + */ +extern void +xen_xspolicy_record_free(xen_xspolicy_record *record); + + +typedef struct xen_xspolicy_record_opt +{ + bool is_record; + union + { + xen_xspolicy handle; + xen_xspolicy_record *record; + } u; +} xen_xspolicy_record_opt; + +/** + * Allocate a xen_xspolicy_record_opt. + */ +extern xen_xspolicy_record_opt * +xen_xspolicy_record_opt_alloc(void); + +/** + * Free the given xen_xspolicy_record_opt, and all referenced values. The + * given record_opt must have been allocated by this library. + */ +extern void +xen_xspolicy_record_opt_free(xen_xspolicy_record_opt *record_opt); + + +typedef struct xen_xspolicy_record_set +{ + size_t size; + xen_xspolicy_record *contents[]; +} xen_xspolicy_record_set; + +/** + * Allocate a xen_xspolicy_record_set of the given size. + */ +extern xen_xspolicy_record_set * +xen_xspolicy_record_set_alloc(size_t size); + +/** + * Free the given xen_xspolicy_record_set, and all referenced values. The + * given set must have been allocated by this library. + */ +extern void +xen_xspolicy_record_set_free(xen_xspolicy_record_set *set); + +/** + * Data structures and function declarations for an XS Policy's state + * information. + */ +typedef struct xen_xs_policystate +{ + xen_xspolicy_record_opt *xs_ref; + int64_t xserr; + char *repr; + xs_type type; + xs_instantiationflags flags; + char *version; + char *errors; +} xen_xs_policystate; + +void +xen_xs_policystate_free(xen_xs_policystate *state); + + +/** + * Get the referenced policy's record. + */ +bool +xen_xspolicy_get_record(xen_session *session, xen_xspolicy_record **result, + xen_xspolicy xspolicy); + +/** + * Get the UUID field of the given policy. + */ +bool +xen_xspolicy_get_uuid(xen_session *session, char **result, + xen_xspolicy xspolicy); + +/** + * Get a policy given it's UUID + */ +bool +xen_xspolicy_get_by_uuid(xen_session *session, xen_xspolicy *result, + char *uuid); + + +/** + * Get the types of policies supported by the system. + */ +bool +xen_xspolicy_get_xstype(xen_session *session, xs_type *result); + + +/** + * Get information about the currently managed policy. + * (The API allows only one policy to be on the system.) + */ +bool +xen_xspolicy_get_xspolicy(xen_session *session, xen_xs_policystate **result); + +/** + * Activate the referenced policy by loading it into the hypervisor. + */ +bool +xen_xspolicy_activate_xspolicy(xen_session *session, int64_t *result, + xen_xspolicy xspolicy, + xs_instantiationflags flags); + + +/** + * Set the system's policy to the given information comprising + * type of policy, the xml representation of the policy, some flags + * on whether to load the policy immediately and whether to overwrite + * an existing policy on the system. + */ +bool +xen_xspolicy_set_xspolicy(xen_session *session, xen_xs_policystate **result, + xs_type type, char *repr, int64_t flags, + bool overwrite); + + +/** + * Remove any policy from having the system booted with. + */ +extern bool +xen_xspolicy_rm_xsbootpolicy(xen_session *session); + +/** + * Retrieve all labeled resources. + */ +extern bool +xen_xspolicy_get_labeled_resources(xen_session *session, + xen_string_string_map **resources); + +/** + * Label a resource such as for example a hard drive partition or file + */ +extern bool +xen_xspolicy_set_resource_label(xen_session *session, + char *resource, char *label, + char *oldlabel); + +/** + * Get the label of a resource. + */ +extern bool +xen_xspolicy_get_resource_label(xen_session *session, char **label, + char *resource); + +#endif diff -r c9720159b983 -r 9559ba7c80f9 tools/libxen/include/xen/api/xen_xspolicy_decl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/libxen/include/xen/api/xen_xspolicy_decl.h Tue Jul 17 10:20:21 2007 +0100 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2007, IBM Corp. + * Copyright (c) 2007, XenSource Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef XEN_XSPOLICY_DECL_H +#define XEN_XSPOLICY_DECL_H + +typedef void *xen_xspolicy; + +struct xen_xspolicy_set; +struct xen_xspolicy_record; +struct xen_xspolicy_record_set; +struct xen_xspolicy_record_opt; +struct xen_xspolicy_record_opt_set; + +#endif diff -r c9720159b983 -r 9559ba7c80f9 tools/libxen/src/xen_acmpolicy.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/libxen/src/xen_acmpolicy.c Tue Jul 17 10:20:21 2007 +0100 @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2007, IBM Corp. + * Copyright (c) 2007, XenSource Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include <stddef.h> +#include <stdlib.h> + +#include "xen_internal.h" +#include "xen/api/xen_common.h" +#include "xen/api/xen_xspolicy.h" +#include "xen/api/xen_acmpolicy.h" + + +static const struct_member xen_acmpolicy_record_struct_members[] = + { + { .key = "uuid", + .type = &abstract_type_string, + .offset = offsetof(xen_acmpolicy_record, uuid) }, + { .key = "flags", + .type = &abstract_type_int, + .offset = offsetof(xen_acmpolicy_record, flags) }, + { .key = "repr", + .type = &abstract_type_string, + .offset = offsetof(xen_acmpolicy_record, repr) }, + { .key = "type", + .type = &abstract_type_int, + .offset = offsetof(xen_acmpolicy_record, type) }, + }; + +const abstract_type xen_acmpolicy_record_abstract_type_ = + { + .typename = STRUCT, + .struct_size = sizeof(xen_acmpolicy_record), + .member_count = + sizeof(xen_acmpolicy_record_struct_members) / sizeof(struct_member), + .members = xen_acmpolicy_record_struct_members + }; + + +static const struct_member xen_acm_header_struct_members[] = + { + { .key = "policyname", + .type = &abstract_type_string, + .offset = offsetof(xen_acm_header, policyname) }, + { .key = "policyurl", + .type = &abstract_type_string, + .offset = offsetof(xen_acm_header, policyurl) }, + { .key = "date", + .type = &abstract_type_string, + .offset = offsetof(xen_acm_header, date) }, + { .key = "reference", + .type = &abstract_type_string, + .offset = offsetof(xen_acm_header, reference) }, + { .key = "namespaceurl", + .type = &abstract_type_string, + .offset = offsetof(xen_acm_header, namespaceurl) }, + { .key = "version", + .type = &abstract_type_string, + .offset = offsetof(xen_acm_header, version) }, + }; + +const abstract_type xen_acm_header_abstract_type_ = + { + .typename = STRUCT, + .struct_size = sizeof(xen_acm_header), + .member_count = + sizeof(xen_acm_header_struct_members) / + sizeof(struct_member), + .members = xen_acm_header_struct_members, + }; + +void +xen_acm_header_free(xen_acm_header *shdr) +{ + if (shdr == NULL) + { + return; + } + free(shdr->policyname); + free(shdr->policyurl); + free(shdr->date); + free(shdr->reference); + free(shdr->namespaceurl); + free(shdr->version); + free(shdr); +} + + +void +xen_acmpolicy_record_free(xen_acmpolicy_record *record) +{ + if (record == NULL) + { + return; + } + free(record->handle); + free(record->uuid); + free(record->repr); + free(record); +} + + + +bool +xen_acmpolicy_get_record(xen_session *session, xen_acmpolicy_record **result, + xen_xspolicy xspolicy) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = xspolicy } + }; + + abstract_type result_type = xen_acmpolicy_record_abstract_type_; + + *result = NULL; + XEN_CALL_("ACMPolicy.get_record"); + + if (session->ok) + { + (*result)->handle = xen_strdup_((*result)->uuid); + } + + return session->ok; +} + + +bool +xen_acmpolicy_get_header(xen_session *session, + xen_acm_header **result, + xen_xspolicy xspolicy) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = xspolicy }, + }; + + abstract_type result_type = xen_acm_header_abstract_type_; + + *result = NULL; + XEN_CALL_("ACMPolicy.get_header"); + return session->ok; +} + + +bool +xen_acmpolicy_get_xml(xen_session *session, + char **result, + xen_xspolicy xspolicy) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = xspolicy }, + }; + + abstract_type result_type = abstract_type_string; + + *result = NULL; + XEN_CALL_("ACMPolicy.get_xml"); + return session->ok; +} + + +bool +xen_acmpolicy_get_map(xen_session *session, + char **result, + xen_xspolicy xspolicy) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = xspolicy }, + }; + + abstract_type result_type = abstract_type_string; + + *result = NULL; + XEN_CALL_("ACMPolicy.get_map"); + return session->ok; +} + + +bool +xen_acmpolicy_get_binary(xen_session *session, char **result, + xen_xspolicy xspolicy) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = xspolicy }, + }; + + abstract_type result_type = abstract_type_string; + + *result = NULL; + XEN_CALL_("ACMPolicy.get_binary"); + return session->ok; +} + + +bool +xen_acmpolicy_get_uuid(xen_session *session, char **result, + xen_xspolicy xspolicy) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = xspolicy } + }; + + abstract_type result_type = abstract_type_string; + + *result = NULL; + XEN_CALL_("ACMPolicy.get_uuid"); + return session->ok; +} diff -r c9720159b983 -r 9559ba7c80f9 tools/libxen/src/xen_vdi.c --- a/tools/libxen/src/xen_vdi.c Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/libxen/src/xen_vdi.c Tue Jul 17 10:20:21 2007 +0100 @@ -534,3 +534,42 @@ xen_vdi_get_uuid(xen_session *session, c XEN_CALL_("VDI.get_uuid"); return session->ok; } + + +bool +xen_vdi_set_security_label(xen_session *session, int64_t *result, xen_vdi vdi, + char *label, char *oldlabel) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = vdi }, + { .type = &abstract_type_string, + .u.string_val = label }, + { .type = &abstract_type_string, + .u.string_val = oldlabel }, + }; + + abstract_type result_type = abstract_type_int; + + *result = 0; + XEN_CALL_("VDI.set_security_label"); + return session->ok; +} + + +bool +xen_vdi_get_security_label(xen_session *session, char **result, xen_vdi vdi) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = vdi }, + }; + + abstract_type result_type = abstract_type_string; + + *result = NULL; + XEN_CALL_("VDI.get_security_label"); + return session->ok; +} diff -r c9720159b983 -r 9559ba7c80f9 tools/libxen/src/xen_vm.c --- a/tools/libxen/src/xen_vm.c Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/libxen/src/xen_vm.c Tue Jul 17 10:20:21 2007 +0100 @@ -162,7 +162,10 @@ static const struct_member xen_vm_record .offset = offsetof(xen_vm_record, metrics) }, { .key = "guest_metrics", .type = &abstract_type_ref, - .offset = offsetof(xen_vm_record, guest_metrics) } + .offset = offsetof(xen_vm_record, guest_metrics) }, + { .key = "security_label", + .type = &abstract_type_string, + .offset = offsetof(xen_vm_record, security_label) } }; const abstract_type xen_vm_record_abstract_type_ = @@ -206,6 +209,7 @@ xen_vm_record_free(xen_vm_record *record xen_string_string_map_free(record->other_config); xen_vm_metrics_record_opt_free(record->metrics); xen_vm_guest_metrics_record_opt_free(record->guest_metrics); + free(record->security_label); free(record); } @@ -1738,3 +1742,42 @@ xen_vm_get_uuid(xen_session *session, ch XEN_CALL_("VM.get_uuid"); return session->ok; } + + +bool +xen_vm_set_security_label(xen_session *session, int64_t *result, xen_vm vm, + char *label, char *oldlabel) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = vm }, + { .type = &abstract_type_string, + .u.string_val = label }, + { .type = &abstract_type_string, + .u.string_val = oldlabel }, + }; + + abstract_type result_type = abstract_type_int; + + *result = 0; + XEN_CALL_("VM.set_security_label"); + return session->ok; +} + + +bool +xen_vm_get_security_label(xen_session *session, char **result, xen_vm vm) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = vm }, + }; + + abstract_type result_type = abstract_type_string; + + *result = NULL; + XEN_CALL_("VM.get_security_label"); + return session->ok; +} diff -r c9720159b983 -r 9559ba7c80f9 tools/libxen/src/xen_xspolicy.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/libxen/src/xen_xspolicy.c Tue Jul 17 10:20:21 2007 +0100 @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2007, IBM Corp. + * Copyright (c) 2007, XenSource Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include <stddef.h> +#include <stdlib.h> + +#include "xen/api/xen_common.h" +#include "xen/api/xen_internal.h" +#include "xen/api/xen_xspolicy.h" + + +XEN_FREE(xen_xspolicy) +XEN_SET_ALLOC_FREE(xen_xspolicy) +XEN_RECORD_OPT_FREE(xen_xspolicy) + +static const struct_member xen_xspolicy_record_struct_members[] = + { + { .key = "uuid", + .type = &abstract_type_string, + .offset = offsetof(xen_xspolicy_record, uuid) }, + { .key = "flags", + .type = &abstract_type_int, + .offset = offsetof(xen_xspolicy_record, flags) }, + { .key = "repr", + .type = &abstract_type_string, + .offset = offsetof(xen_xspolicy_record, repr) }, + { .key = "type", + .type = &abstract_type_int, + .offset = offsetof(xen_xspolicy_record, type) }, + }; + +const abstract_type xen_xspolicy_record_abstract_type_ = + { + .typename = STRUCT, + .struct_size = sizeof(xen_xspolicy_record), + .member_count = + sizeof(xen_xspolicy_record_struct_members) / sizeof(struct_member), + .members = xen_xspolicy_record_struct_members + }; + + +static const struct_member xen_xs_policystate_struct_members[] = + { + { .key = "xs_ref", + .type = &abstract_type_ref, + .offset = offsetof(xen_xs_policystate, xs_ref) }, + { .key = "xserr", + .type = &abstract_type_int, + .offset = offsetof(xen_xs_policystate, xserr) }, + { .key = "repr", + .type = &abstract_type_string, + .offset = offsetof(xen_xs_policystate, repr) }, + { .key = "type", + .type = &abstract_type_int, + .offset = offsetof(xen_xs_policystate, type) }, + { .key = "flags", + .type = &abstract_type_int, + .offset = offsetof(xen_xs_policystate, flags) }, + { .key = "version", + .type = &abstract_type_string, + .offset = offsetof(xen_xs_policystate, version) }, + { .key = "errors", + .type = &abstract_type_string, + .offset = offsetof(xen_xs_policystate, errors) }, + }; + +const abstract_type xen_xs_policystate_abstract_type_ = + { + .typename = STRUCT, + .struct_size = sizeof(xen_xs_policystate), + .member_count = + sizeof(xen_xs_policystate_struct_members) / + sizeof(struct_member), + .members = xen_xs_policystate_struct_members, + }; + + + + +void +xen_xs_policystate_free(xen_xs_policystate *state) +{ + if (state == NULL) + { + return; + } + xen_xspolicy_record_opt_free(state->xs_ref); + free(state->repr); + free(state->errors); + free(state->version); + free(state); +} + + +void +xen_xspolicy_record_free(xen_xspolicy_record *record) +{ + if (record == NULL) + { + return; + } + free(record->handle); + free(record->uuid); + free(record->repr); + free(record); +} + + +bool +xen_xspolicy_get_record(xen_session *session, xen_xspolicy_record **result, + xen_xspolicy xspolicy) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = xspolicy } + }; + + abstract_type result_type = xen_xspolicy_record_abstract_type_; + + *result = NULL; + XEN_CALL_("XSPolicy.get_record"); + + if (session->ok) + { + (*result)->handle = xen_strdup_((*result)->uuid); + } + + return session->ok; +} + + +bool +xen_xspolicy_get_uuid(xen_session *session, char **result, + xen_xspolicy xspolicy) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = xspolicy } + }; + + abstract_type result_type = abstract_type_string; + + *result = NULL; + XEN_CALL_("XSPolicy.get_uuid"); + return session->ok; +} + + +bool +xen_xspolicy_get_by_uuid(xen_session *session, xen_xspolicy *result, + char *uuid) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = uuid } + }; + + abstract_type result_type = abstract_type_string; + + *result = NULL; + XEN_CALL_("XSPolicy.get_by_uuid"); + return session->ok; +} + + +bool +xen_xspolicy_get_xstype(xen_session *session, xs_type *result) +{ + abstract_value param_values[] = + { + }; + + abstract_type result_type = abstract_type_int; + + *result = 0; + XEN_CALL_("XSPolicy.get_xstype"); + return session->ok; +} + + +bool +xen_xspolicy_set_xspolicy(xen_session *session, xen_xs_policystate **result, + xs_type type, char *repr, + xs_instantiationflags flags, + bool overwrite) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_int, + .u.int_val = type }, + { .type = &abstract_type_string, + .u.string_val = repr }, + { .type = &abstract_type_int, + .u.int_val = flags }, + { .type = &abstract_type_bool, + .u.bool_val = overwrite } + }; + + abstract_type result_type = xen_xs_policystate_abstract_type_; + + *result = NULL; + XEN_CALL_("XSPolicy.set_xspolicy"); + return session->ok; +} + + +bool +xen_xspolicy_get_xspolicy(xen_session *session, xen_xs_policystate **result) +{ + abstract_value param_values[] = + { + }; + + abstract_type result_type = xen_xs_policystate_abstract_type_; + + *result = NULL; + XEN_CALL_("XSPolicy.get_xspolicy"); + return session->ok; +} + + +bool +xen_xspolicy_get_labeled_resources(xen_session *session, + xen_string_string_map **result) +{ + abstract_value param_values[] = + { + }; + + abstract_type result_type = abstract_type_string_string_map; + + *result = NULL; + XEN_CALL_("XSPolicy.get_labeled_resources"); + return session->ok; +} + + +bool +xen_xspolicy_set_resource_label(xen_session *session, + char *resource, char *label, + char *oldlabel) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = resource }, + { .type = &abstract_type_string, + .u.string_val = label }, + { .type = &abstract_type_string, + .u.string_val = oldlabel }, + }; + + xen_call_(session, "XSPolicy.set_resource_label", param_values, 3, + NULL, NULL); + return session->ok; +} + + +bool +xen_xspolicy_get_resource_label(xen_session *session, char **result, + char *resource) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = resource }, + }; + + abstract_type result_type = abstract_type_string; + XEN_CALL_("XSPolicy.get_resource_label"); + return session->ok; +} + + +bool +xen_xspolicy_rm_xsbootpolicy(xen_session *session) +{ + abstract_value param_values[] = + { + }; + + xen_call_(session, "XSPolicy.rm_xsbootpolicy", param_values, 0, + NULL, NULL); + return session->ok; +} + + +bool +xen_xspolicy_activate_xspolicy(xen_session *session, + xs_instantiationflags *result, + xen_xspolicy xspolicy, + xs_instantiationflags flags) +{ + abstract_value param_values[] = + { + { .type = &abstract_type_string, + .u.string_val = xspolicy }, + { .type = &abstract_type_int, + .u.int_val = flags }, + }; + + abstract_type result_type = abstract_type_int; + + *result = 0; + XEN_CALL_("XSPolicy.activate_xspolicy"); + return session->ok; +} diff -r c9720159b983 -r 9559ba7c80f9 tools/python/xen/util/acmpolicy.py --- a/tools/python/xen/util/acmpolicy.py Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/python/xen/util/acmpolicy.py Tue Jul 17 10:20:21 2007 +0100 @@ -57,12 +57,20 @@ class ACMPolicy(XSPolicy): def __init__(self, name=None, dom=None, ref=None, xml=None): if name: self.name = name - self.dom = minidom.parse(self.path_from_policy_name(name)) + try: + self.dom = minidom.parse(self.path_from_policy_name(name)) + except Exception, e: + raise SecurityError(-xsconstants.XSERR_XML_PROCESSING, + str(e)) elif dom: self.dom = dom self.name = self.get_name() elif xml: - self.dom = minidom.parseString(xml) + try: + self.dom = minidom.parseString(xml) + except Exception, e: + raise SecurityError(-xsconstants.XSERR_XML_PROCESSING, + str(e)) self.name = self.get_name() rc = self.validate() if rc != xsconstants.XSERR_SUCCESS: @@ -481,7 +489,8 @@ class ACMPolicy(XSPolicy): strings = [] i = 0 while i < len(node.childNodes): - if node.childNodes[i].nodeName == "Type": + if node.childNodes[i].nodeName == "Type" and \ + len(node.childNodes[i].childNodes) > 0: strings.append(node.childNodes[i].childNodes[0].nodeValue) i += 1 return strings @@ -564,7 +573,8 @@ class ACMPolicy(XSPolicy): while i < len(node.childNodes): if node.childNodes[i].nodeName == "VirtualMachineLabel": name = self.policy_dom_get(node.childNodes[i], "Name") - strings.append(name.childNodes[0].nodeValue) + if len(name.childNodes) > 0: + strings.append(name.childNodes[0].nodeValue) i += 1 return strings @@ -592,23 +602,24 @@ class ACMPolicy(XSPolicy): i = 0 while i < len(node.childNodes): if node.childNodes[i].nodeName == "VirtualMachineLabel": - _res = {} - _res['type'] = xsconstants.ACM_LABEL_VM name = self.policy_dom_get(node.childNodes[i], "Name") - _res['name'] = name.childNodes[0].nodeValue - stes = self.policy_dom_get(node.childNodes[i], - "SimpleTypeEnforcementTypes") - if stes: - _res['stes'] = self.policy_get_types(stes) - else: - _res['stes'] = [] - chws = self.policy_dom_get(node.childNodes[i], - "ChineseWallTypes") - if chws: - _res['chws'] = self.policy_get_types(chws) - else: - _res['chws'] = [] - res.append(_res) + if len(name.childNodes) > 0: + _res = {} + _res['type'] = xsconstants.ACM_LABEL_VM + _res['name'] = name.childNodes[0].nodeValue + stes = self.policy_dom_get(node.childNodes[i], + "SimpleTypeEnforcementTypes") + if stes: + _res['stes'] = self.policy_get_types(stes) + else: + _res['stes'] = [] + chws = self.policy_dom_get(node.childNodes[i], + "ChineseWallTypes") + if chws: + _res['chws'] = self.policy_get_types(chws) + else: + _res['chws'] = [] + res.append(_res) i += 1 return res @@ -628,7 +639,8 @@ class ACMPolicy(XSPolicy): while i < len(node.childNodes): if node.childNodes[i].nodeName == labeltype: name = self.policy_dom_get(node.childNodes[i], "Name") - if name.childNodes[0].nodeValue == label: + if len(name.childNodes) > 0 and \ + name.childNodes[0].nodeValue == label: stes = self.policy_dom_get(node.childNodes[i], "SimpleTypeEnforcementTypes") if not stes: @@ -662,7 +674,7 @@ class ACMPolicy(XSPolicy): if node.childNodes[i].nodeName == labeltype: name = self.policy_dom_get(node.childNodes[i], "Name") from_name = name.getAttribute("from") - if from_name: + if from_name and len(name.childNodes) > 0: res.update({from_name : name.childNodes[0].nodeValue}) i += 1 return res @@ -700,7 +712,7 @@ class ACMPolicy(XSPolicy): name = self.policy_dom_get(node.childNodes[i], "Name") stes = self.policy_dom_get(node.childNodes[i], "SimpleTypeEnforcementTypes") - if stes: + if stes and len(name.childNodes) > 0: strings.append(name.childNodes[0].nodeValue) i += 1 return strings @@ -715,18 +727,19 @@ class ACMPolicy(XSPolicy): i = 0 while i < len(node.childNodes): if node.childNodes[i].nodeName == "ResourceLabel": - _res = {} - _res['type'] = xsconstants.ACM_LABEL_RES name = self.policy_dom_get(node.childNodes[i], "Name") - _res['name'] = name.childNodes[0].nodeValue - stes = self.policy_dom_get(node.childNodes[i], - "SimpleTypeEnforcementTypes") - if stes: - _res['stes'] = self.policy_get_types(stes) - else: - _res['stes'] = [] - _res['chws'] = [] - res.append(_res) + if len(name.childNodes) > 0: + _res = {} + _res['type'] = xsconstants.ACM_LABEL_RES + _res['name'] = name.childNodes[0].nodeValue + stes = self.policy_dom_get(node.childNodes[i], + "SimpleTypeEnforcementTypes") + if stes: + _res['stes'] = self.policy_get_types(stes) + else: + _res['stes'] = [] + _res['chws'] = [] + res.append(_res) i += 1 return res diff -r c9720159b983 -r 9559ba7c80f9 tools/python/xen/util/security.py --- a/tools/python/xen/util/security.py Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/python/xen/util/security.py Tue Jul 17 10:20:21 2007 +0100 @@ -154,75 +154,6 @@ def calc_dom_ssidref_from_info(info): return 0 raise VmError("security.calc_dom_ssidref_from_info: info of type '%s'" "not supported." % type(info)) - -# Assumes a 'security' info [security access_control ...] [ssidref ...] -def get_security_info(info, field): - """retrieves security field from self.info['security']) - allowed search fields: ssidref, label, policy - """ - if isinstance(info, dict): - security = info['security'] - elif isinstance(info, list): - security = sxp.child_value(info, 'security') - if not security: - if field == 'ssidref': - #return default ssid - return 0 - else: - err("Security information not found in info struct.") - - if field == 'ssidref': - search = 'ssidref' - elif field in ['policy', 'label']: - search = 'access_control' - else: - err("Illegal field in get_security_info.") - - for idx in range(0, len(security)): - if search != security[idx][0]: - continue - if search == 'ssidref': - return int(security[idx][1]) - else: - for aidx in range(0, len(security[idx])): - if security[idx][aidx][0] == field: - return str(security[idx][aidx][1]) - - if search == 'ssidref': - return 0 - else: - return None - - -def get_security_printlabel(info): - """retrieves printable security label from self.info['security']), - preferably the label name and otherwise (if label is not specified - in config and cannot be found in mapping file) a hex string of the - ssidref or none if both not available - """ - try: - if not on(): - return "INACTIVE" - if active_policy in ["DEFAULT"]: - return "DEFAULT" - - printlabel = get_security_info(info, 'label') - if printlabel: - return printlabel - ssidref = get_security_info(info, 'ssidref') - if not ssidref: - return None - #try to translate ssidref to a label - result = ssidref2label(ssidref) - if not result: - printlabel = "0x%08x" % ssidref - else: - printlabel = result - return printlabel - except ACMError: - #don't throw an exception in xm list - return "ERROR" - def getmapfile(policyname): diff -r c9720159b983 -r 9559ba7c80f9 tools/python/xen/xend/XendConfig.py --- a/tools/python/xen/xend/XendConfig.py Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/python/xen/xend/XendConfig.py Tue Jul 17 10:20:21 2007 +0100 @@ -636,6 +636,8 @@ class XendConfig(dict): except ValueError, e: raise XendConfigError('cpus = %s: %s' % (cfg['cpus'], e)) + if not 'security' in cfg and sxp.child_value(sxp_cfg, 'security'): + cfg['security'] = sxp.child_value(sxp_cfg, 'security') if 'security' in cfg and not cfg.get('security_label'): secinfo = cfg['security'] if isinstance(secinfo, list): diff -r c9720159b983 -r 9559ba7c80f9 tools/python/xen/xend/XendDomain.py --- a/tools/python/xen/xend/XendDomain.py Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/python/xen/xend/XendDomain.py Tue Jul 17 10:20:21 2007 +0100 @@ -1164,6 +1164,10 @@ class XendDomain: if dominfo.getDomid() == DOM0_ID: raise XendError("Cannot dump core for privileged domain %s" % domid) + if dominfo._stateGet() not in (DOM_STATE_PAUSED, DOM_STATE_RUNNING): + raise VMBadState("Domain '%s' is not started" % domid, + POWER_STATE_NAMES[DOM_STATE_PAUSED], + POWER_STATE_NAMES[dominfo._stateGet()]) try: log.info("Domain core dump requested for domain %s (%d) " @@ -1537,6 +1541,10 @@ class XendDomain: dominfo = self.domain_lookup_nr(domid) if not dominfo: raise XendInvalidDomain(str(domid)) + if dominfo._stateGet() not in (DOM_STATE_RUNNING, DOM_STATE_PAUSED): + raise VMBadState("Domain '%s' is not started" % domid, + POWER_STATE_NAMES[DOM_STATE_RUNNING], + POWER_STATE_NAMES[dominfo._stateGet()]) if trigger_name.lower() in TRIGGER_TYPE: trigger = TRIGGER_TYPE[trigger_name.lower()] else: diff -r c9720159b983 -r 9559ba7c80f9 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/python/xen/xend/XendDomainInfo.py Tue Jul 17 10:20:21 2007 +0100 @@ -459,6 +459,7 @@ class XendDomainInfo: hvm_pvdrv = xc.hvm_get_param(self.domid, HVM_PARAM_CALLBACK_IRQ) if not hvm_pvdrv: code = REVERSE_DOMAIN_SHUTDOWN_REASONS[reason] + xc.domain_destroy_hook(self.domid) log.info("HVM save:remote shutdown dom %d!", self.domid) xc.domain_shutdown(self.domid, code) @@ -1593,6 +1594,7 @@ class XendDomainInfo: log.exception("Removing domain path failed.") self._stateSet(DOM_STATE_HALTED) + self.domid = None # Do not push into _stateSet()! finally: self.refresh_shutdown_lock.release() diff -r c9720159b983 -r 9559ba7c80f9 tools/python/xen/xm/activatepolicy.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/python/xen/xm/activatepolicy.py Tue Jul 17 10:20:21 2007 +0100 @@ -0,0 +1,86 @@ +#============================================================================ +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#============================================================================ +# Copyright (C) 2007 International Business Machines Corp. +# Author: Stefan Berger <stefanb@xxxxxxxxxx> +#============================================================================ + +"""Activate the managed policy of the system. +""" + +import sys +from xen.util import xsconstants +from xml.dom import minidom +from xen.xm.opts import OptionError +from xen.xm import getpolicy +from xen.xm import main as xm_main +from xen.xm.main import server + +def help(): + return """ + Usage: xm activatepolicy [options] + + Activate the xend-managed policy. + + The following options are defined: + --load Load the policy into the hypervisor. + --boot Have the system boot with the policy. Changes the default + title in grub.conf. + --noboot Remove the policy from the default entry in grub.conf. + """ + +def activate_policy(flags): + policystate = server.xenapi.XSPolicy.get_xspolicy() + xs_ref = policystate['xs_ref'] + if int(policystate['type']) == 0 or xs_ref == "": + print "No policy is installed." + return + rc = int(server.xenapi.XSPolicy.activate_xspolicy(xs_ref, flags)) + if rc == flags: + print "Successfully activated the policy." + else: + print "An error occurred trying to activate the policy: %s" % \ + xsconstants.xserr2string(rc) + +def remove_bootpolicy(): + server.xenapi.XSPolicy.rm_xsbootpolicy() + +def main(argv): + if xm_main.serverType != xm_main.SERVER_XEN_API: + raise OptionError('xm needs to be configured to use the xen-api.') + flags = 0 + c = 1 + + while c < len(argv): + if '--boot' == argv[c]: + flags |= xsconstants.XS_INST_BOOT + elif '--load' == argv[c]: + flags |= xsconstants.XS_INST_LOAD + elif '--noboot' == argv[c]: + remove_bootpolicy() + else: + raise OptionError("Unknown command line option '%s'" % argv[c]) + c += 1 + + if flags != 0: + activate_policy(flags) + + getpolicy.getpolicy(False) + +if __name__ == '__main__': + try: + main(sys.argv) + except Exception, e: + sys.stderr.write('Error: %s\n' % str(e)) + sys.exit(-1) diff -r c9720159b983 -r 9559ba7c80f9 tools/python/xen/xm/addlabel.py --- a/tools/python/xen/xm/addlabel.py Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/python/xen/xm/addlabel.py Tue Jul 17 10:20:21 2007 +0100 @@ -25,17 +25,29 @@ from xen.util import dictio from xen.util import dictio from xen.util import security from xen.xm.opts import OptionError +from xen.util import xsconstants +from xen.xm import main as xm_main +from xen.xm.main import server def help(): return """ Format: xm addlabel <label> dom <configfile> [<policy>] - xm addlabel <label> res <resource> [<policy>] + xm addlabel <label> mgt <domain name> [<policy type>:<policy>] + xm addlabel <label> res <resource> [[<policy type>:]<policy>] This program adds an acm_label entry into the 'configfile' - for a domain or to the global resource label file for a - resource. It derives the policy from the running hypervisor + for a domain or allows to label a xend-managed domain. + The global resource label file for is extended with labels for + resources. It derives the policy from the running hypervisor if it is not given (optional parameter). If a label already - exists for the given domain or resource, then addlabel fails.""" + exists for the given domain or resource, then addlabel fails. + + For xend-managed domains, the 'mgt' parameter should be used and + the 'xm' tool must have been configured to use the xen-api for + communication with xen. If a policy is provided as last parameter, + its type must also be given. Currently only one type of policy is + supported and identified as 'ACM'. An example for a valid string + is 'ACM:xm-test'. """ def validate_config_file(configfile): @@ -66,32 +78,47 @@ def validate_config_file(configfile): return 1 -def add_resource_label(label, resource, policyref): +def add_resource_label(label, resource, policyref, policy_type): """Adds a resource label to the global resource label file. """ - # sanity check: make sure this label can be instantiated later on - ssidref = security.label2ssidref(label, policyref, 'res') - - #build canonical resource name - resource = security.unify_resname(resource) - - # see if this resource is already in the file - access_control = {} - file = security.res_label_filename - try: - access_control = dictio.dict_read("resources", file) - except: - print "Resource file not found, creating new file at:" - print "%s" % (file) - - if access_control.has_key(resource): - security.err("This resource is already labeled.") - - # write the data to file - new_entry = { resource : tuple([policyref, label]) } - access_control.update(new_entry) - dictio.dict_write(access_control, "resources", file) - + + if xm_main.serverType != xm_main.SERVER_XEN_API: + + # sanity check: make sure this label can be instantiated later on + ssidref = security.label2ssidref(label, policyref, 'res') + + #build canonical resource name + resource = security.unify_resname(resource,mustexist=False) + + # see if this resource is already in the file + access_control = {} + fil = security.res_label_filename + try: + access_control = dictio.dict_read("resources", fil) + except: + print "Resource file not found, creating new file at:" + print "%s" % (fil) + + if access_control.has_key(resource): + security.err("This resource is already labeled.") + + # write the data to file + new_entry = { resource : tuple([policy_type, policyref, label]) } + access_control.update(new_entry) + dictio.dict_write(access_control, "resources", fil) + else: + res = [ policy_type, policyref, label ] + res_xapi = security.format_resource_label(res) + old = server.xenapi.XSPolicy.get_resource_label(resource) + if old == "": + try: + server.xenapi.XSPolicy.set_resource_label(resource, + res_xapi, + "") + except Exception, e: + security.err("Could not label this resource: %s" % e) + else: + security.err("'%s' is already labeled with '%s'" % (resource,old)) def add_domain_label(label, configfile, policyref): # sanity checks: make sure this label can be instantiated later on @@ -109,9 +136,35 @@ def add_domain_label(label, configfile, config_fd.write(new_label) config_fd.close() +def add_domain_label_xapi(label, domainname, policyref, policy_type): + if xm_main.serverType != xm_main.SERVER_XEN_API: + raise OptionError('Xm must be configured to use the xen-api.') + uuids = server.xenapi.VM.get_by_name_label(domainname) + if len(uuids) == 0: + raise OptionError('A VM with that name does not exist.') + if len(uuids) != 1: + raise OptionError('There are multiple domains with the same name.') + uuid = uuids[0] + sec_lab = "%s:%s:%s" % (policy_type, policyref, label) + try: + old_lab = server.xenapi.VM.get_security_label(uuid) + rc = server.xenapi.VM.set_security_label(uuid, sec_lab, old_lab) + except: + rc = -1 + if int(rc) < 0: + raise OptionError('Could not label domain.') + else: + ssidref = int(rc) + if ssidref != 0: + print "Set the label of domain '%s' to '%s'. New ssidref = %08x" % \ + (domainname,label,ssidref) + else: + print "Set the label of dormant domain '%s' to '%s'." % \ + (domainname,label) def main(argv): policyref = None + policy_type = "" if len(argv) not in (4, 5): raise OptionError('Needs either 2 or 3 arguments') @@ -121,6 +174,7 @@ def main(argv): policyref = argv[4] elif security.on(): policyref = security.active_policy + policy_type = xsconstants.ACM_POLICY_ID else: raise OptionError("No active policy. Must specify policy on the " "command line.") @@ -136,11 +190,27 @@ def main(argv): raise OptionError('Invalid config file') else: add_domain_label(label, configfile, policyref) + elif argv[2].lower() == "mgt": + domain = argv[3] + if policy_type == "": + tmp = policyref.split(":") + if len(tmp) != 2: + raise OptionError("Policy name in wrong format.") + policy_type, policyref = tmp + add_domain_label_xapi(label, domain, policyref, policy_type) elif argv[2].lower() == "res": resource = argv[3] - add_resource_label(label, resource, policyref) - else: - raise OptionError('Need to specify either "dom" or "res" as ' + if policy_type == "": + tmp = policyref.split(":") + if len(tmp) == 1: + policy_type = xsconstants.ACM_POLICY_ID + elif len(tmp) == 2: + policy_type, policyref = tmp + else: + raise OptionError("Policy name in wrong format.") + add_resource_label(label, resource, policyref, policy_type) + else: + raise OptionError('Need to specify either "dom", "mgt" or "res" as ' 'object to add label to.') if __name__ == '__main__': @@ -149,6 +219,3 @@ if __name__ == '__main__': except Exception, e: sys.stderr.write('Error: %s\n' % str(e)) sys.exit(-1) - - - diff -r c9720159b983 -r 9559ba7c80f9 tools/python/xen/xm/cfgbootpolicy.py --- a/tools/python/xen/xm/cfgbootpolicy.py Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/python/xen/xm/cfgbootpolicy.py Tue Jul 17 10:20:21 2007 +0100 @@ -31,7 +31,11 @@ from xen.util.security import boot_filen from xen.util.security import boot_filename, altboot_filename from xen.util.security import any_title_re, xen_kernel_re, any_module_re from xen.util.security import empty_line_re, binary_name_re, policy_name_re +from xen.util import xsconstants from xen.xm.opts import OptionError +from xen.xm import main as xm_main +from xen.xm.main import server +from xen.util.acmpolicy import ACMPolicy def help(): return """ @@ -144,6 +148,39 @@ def insert_policy(boot_file, alt_boot_fi pass return extended_titles[0] +def cfgbootpolicy_xapi(policy, user_title=None): + xstype = int(server.xenapi.XSPolicy.get_xstype()) + if xstype & xsconstants.XS_POLICY_ACM == 0: + raise OptionError("ACM policy not supported on system.") + if user_title: + raise OptionError("Only the default title is supported with Xen-API.") + + policystate = server.xenapi.XSPolicy.get_xspolicy() + if int(policystate['type']) == 0: + print "No policy is installed." + return + + if int(policystate['type']) != xsconstants.XS_POLICY_ACM: + print "Unknown policy type '%s'." % policystate['type'] + return + else: + xml = policystate['repr'] + xs_ref = policystate['xs_ref'] + if not xml: + OptionError("No policy installed on system?") + acmpol = ACMPolicy(xml=xml) + if acmpol.get_name() != policy: + OptionError("Policy installed on system '%s' does not match the " + "request policy '%s'" % (acmpol.get_name(), policy)) + flags = int(policystate['flags']) | xsconstants.XS_INST_BOOT + rc = int(server.xenapi.XSPolicy.activate_xspolicy(xs_ref, flags)) + if rc == flags: + print "Successfully enabled the policy for having the system" \ + " booted with." + else: + print "An error occurred during the operation: %s" % \ + xsconstants.xserr2string(rc) + def main(argv): user_kver = None @@ -159,24 +196,27 @@ def main(argv): if not policy_name_re.match(policy): raise OptionError("Illegal policy name: '%s'" % policy) - policy_file = '/'.join([policy_dir_prefix] + policy.split('.')) - src_binary_policy_file = policy_file + ".bin" - #check if .bin exists or if policy file exists - if not os.path.isfile(src_binary_policy_file): - if not os.path.isfile(policy_file + "-security_policy.xml"): - raise OptionError("Unknown policy '%s'" % policy) - else: - err_msg = "Cannot find binary file for policy '%s'." % policy - err_msg += " Please use makepolicy to create binary file." - raise OptionError(err_msg) - - dst_binary_policy_file = "/boot/" + policy + ".bin" - shutil.copyfile(src_binary_policy_file, dst_binary_policy_file) - - entryname = insert_policy(boot_filename, altboot_filename, - user_title, policy) - print "Boot entry '%s' extended and \'%s\' copied to /boot" \ - % (entryname, policy + ".bin") + if xm_main.serverType == xm_main.SERVER_XEN_API: + cfgbootpolicy_xapi(policy) + else: + policy_file = '/'.join([policy_dir_prefix] + policy.split('.')) + src_binary_policy_file = policy_file + ".bin" + #check if .bin exists or if policy file exists + if not os.path.isfile(src_binary_policy_file): + if not os.path.isfile(policy_file + "-security_policy.xml"): + raise OptionError("Unknown policy '%s'" % policy) + else: + err_msg = "Cannot find binary file for policy '%s'." % policy + err_msg += " Please use makepolicy to create binary file." + raise OptionError(err_msg) + + dst_binary_policy_file = "/boot/" + policy + ".bin" + shutil.copyfile(src_binary_policy_file, dst_binary_policy_file) + + entryname = insert_policy(boot_filename, altboot_filename, + user_title, policy) + print "Boot entry '%s' extended and \'%s\' copied to /boot" \ + % (entryname, policy + ".bin") if __name__ == '__main__': try: diff -r c9720159b983 -r 9559ba7c80f9 tools/python/xen/xm/create.dtd --- a/tools/python/xen/xm/create.dtd Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/python/xen/xm/create.dtd Tue Jul 17 10:20:21 2007 +0100 @@ -38,6 +38,7 @@ memory, vbd*, vif*, + vtpm*, console*, platform*, vcpu_param*, @@ -49,7 +50,8 @@ actions_after_shutdown %NORMAL_EXIT; #REQUIRED actions_after_reboot %NORMAL_EXIT; #REQUIRED actions_after_crash %CRASH_BEHAVIOUR; #REQUIRED - PCI_bus CDATA #REQUIRED> + PCI_bus CDATA #REQUIRED + security_label CDATA #IMPLIED> <!ELEMENT memory EMPTY> <!ATTLIST memory static_min CDATA #REQUIRED @@ -73,6 +75,9 @@ device CDATA #REQUIRED qos_algorithm_type CDATA #REQUIRED network CDATA #IMPLIED> + +<!ELEMENT vtpm (name*)> +<!ATTLIST vtpm backend CDATA #REQUIRED> <!ELEMENT console (other_config*)> <!ATTLIST console protocol (vt100|rfb|rdp) #REQUIRED> diff -r c9720159b983 -r 9559ba7c80f9 tools/python/xen/xm/create.py --- a/tools/python/xen/xm/create.py Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/python/xen/xm/create.py Tue Jul 17 10:20:21 2007 +0100 @@ -643,22 +643,12 @@ def configure_security(config, vals): ['policy', policy], ['label', label] ] - #ssidref cannot be specified together with access_control - if sxp.child_value(config, 'ssidref'): - err("ERROR: SSIDREF and access_control are mutually exclusive but both specified!") - #else calculate ssidre from label + #calculate ssidref from label ssidref = security.label2ssidref(label, policy, 'dom') if not ssidref : err("ERROR calculating ssidref from access_control.") security_label = ['security', [ config_access_control, ['ssidref' , ssidref ] ] ] config.append(security_label) - elif num == 0: - if hasattr(vals, 'ssidref'): - if not security.on(): - err("ERROR: Security ssidref specified but no policy active.") - ssidref = getattr(vals, 'ssidref') - security_label = ['security', [ [ 'ssidref' , int(ssidref) ] ] ] - config.append(security_label) elif num > 1: err("VM config error: Multiple access_control definitions!") @@ -1231,13 +1221,13 @@ def config_security_check(config, verbos except security.ACMError: print " %s: DENIED" % (resource) - (res_label, res_policy) = security.get_res_label(resource) + (poltype, res_label, res_policy) = security.get_res_label(resource) if not res_label: res_label = "" - print " --> res: %s (%s)" % (str(res_label), - str(res_policy)) - print " --> dom: %s (%s)" % (str(domain_label), - str(domain_policy)) + print " --> res: %s (%s:%s)" % (str(res_label), + str(poltype), str(res_policy)) + print " --> dom: %s (%s:%s)" % (str(domain_label), + str(poltype), str(domain_policy)) answer = 0 diff -r c9720159b983 -r 9559ba7c80f9 tools/python/xen/xm/getlabel.py --- a/tools/python/xen/xm/getlabel.py Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/python/xen/xm/getlabel.py Tue Jul 17 10:20:21 2007 +0100 @@ -21,14 +21,19 @@ import sys, os, re import sys, os, re from xen.util import dictio from xen.util import security +from xen.util import xsconstants from xen.xm.opts import OptionError +from xen.xm import main as xm_main +from xen.xm.main import server def help(): return """ Usage: xm getlabel dom <configfile> + xm getlabel mgt <domain name> xm getlabel res <resource> - This program shows the label for a domain or resource.""" + This program shows the label for a domain, resource or virtual network + interface of a Xend-managed domain.""" def get_resource_label(resource): """Gets the resource label @@ -37,17 +42,24 @@ def get_resource_label(resource): resource = security.unify_resname(resource) # read in the resource file - file = security.res_label_filename + fil = security.res_label_filename try: - access_control = dictio.dict_read("resources", file) + access_control = dictio.dict_read("resources", fil) except: raise OptionError("Resource label file not found") # get the entry and print label if access_control.has_key(resource): - policy = access_control[resource][0] - label = access_control[resource][1] - print "policy="+policy+",label="+label + tmp = access_control[resource] + if len(tmp) == 2: + policy, label = tmp + policytype = xsconstants.ACM_POLICY_ID + elif len(tmp) == 3: + policytype, policy, label = tmp + else: + raise security.ACMError("Resource not properly labeled. " + "Please relabel the resource.") + print policytype+":"+policy+":"+label else: raise security.ACMError("Resource not labeled") @@ -89,8 +101,19 @@ def get_domain_label(configfile): data = data.strip() data = data.lstrip("[\'") data = data.rstrip("\']") - print data + print "policytype=%s," % xsconstants.ACM_POLICY_ID + data +def get_domain_label_xapi(domainname): + if xm_main.serverType != xm_main.SERVER_XEN_API: + raise OptionError('xm needs to be configure to use the xen-api.') + uuids = server.xenapi.VM.get_by_name_label(domainname) + if len(uuids) == 0: + raise OptionError('A VM with that name does not exist.') + if len(uuids) != 1: + raise OptionError('There are multiple domains with the same name.') + uuid = uuids[0] + sec_lab = server.xenapi.VM.get_security_label(uuid) + print "%s" %sec_lab def main(argv): if len(argv) != 3: @@ -99,11 +122,15 @@ def main(argv): if argv[1].lower() == "dom": configfile = argv[2] get_domain_label(configfile) + elif argv[1].lower() == "mgt": + domainname = argv[2] + get_domain_label_xapi(domainname) elif argv[1].lower() == "res": resource = argv[2] get_resource_label(resource) else: - raise OptionError('First subcommand argument must be "dom" or "res"') + raise OptionError('First subcommand argument must be "dom"' + ', "mgt" or "res"') if __name__ == '__main__': try: @@ -111,6 +138,4 @@ if __name__ == '__main__': except Exception, e: sys.stderr.write('Error: %s\n' % str(e)) sys.exit(-1) - - diff -r c9720159b983 -r 9559ba7c80f9 tools/python/xen/xm/getpolicy.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/python/xen/xm/getpolicy.py Tue Jul 17 10:20:21 2007 +0100 @@ -0,0 +1,94 @@ +#============================================================================ +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#============================================================================ +# Copyright (C) 2007 International Business Machines Corp. +# Author: Stefan Berger <stefanb@xxxxxxxxxx> +#============================================================================ + +"""Get the managed policy of the system. +""" + +import sys +from xen.util import xsconstants +from xml.dom import minidom +from xen.xm.opts import OptionError +from xen.util.acmpolicy import ACMPolicy +from xen.xm import main as xm_main +from xen.xm.main import server + +def help(): + return """ + Usage: xm getpolicy [options] + + The following options are defined + --dumpxml Display the XML of the policy + + Get the policy managed by xend.""" + +def getpolicy(dumpxml): + if xm_main.serverType != xm_main.SERVER_XEN_API: + raise OptionError('xm needs to be configured to use the xen-api.') + types = [] + xstype = int(server.xenapi.XSPolicy.get_xstype()) + if xstype & xsconstants.XS_POLICY_ACM: + types.append("ACM") + xstype ^= xsconstants.XS_POLICY_ACM + if xstype != 0: + types.append("unsupported (%08x)" % xstype) + print "Supported security subsystems : %s \n" % ", ".join(types) + + policystate = server.xenapi.XSPolicy.get_xspolicy() + if int(policystate['type']) == 0: + print "No policy is installed." + return + if int(policystate['type']) != xsconstants.XS_POLICY_ACM: + print "Unknown policy type '%s'." % policystate['type'] + else: + xml = policystate['repr'] + acmpol = None + if xml: + acmpol = ACMPolicy(xml=xml) + print "Policy installed on the system:" + if acmpol: + print "Policy name : %s" % acmpol.get_name() + print "Policy type : %s" % xsconstants.ACM_POLICY_ID + print "Reference : %s" % policystate['xs_ref'] + print "Version of XML policy : %s" % policystate['version'] + state = [] + flags = int(policystate['flags']) + if flags & xsconstants.XS_INST_LOAD: + state.append("loaded") + if flags & xsconstants.XS_INST_BOOT: + state.append("system booted with") + print "State of the policy : %s" % ", ".join(state) + if dumpxml: + xml = policystate['repr'] + if xml: + dom = minidom.parseString(xml.encode("utf-8")) + print "%s" % dom.toprettyxml(indent=" ",newl="\n") + +def main(argv): + dumpxml = False + + if '--dumpxml' in argv: + dumpxml = True + + getpolicy(dumpxml) + +if __name__ == '__main__': + try: + main(sys.argv) + except Exception, e: + sys.stderr.write('Error: %s\n' % str(e)) + sys.exit(-1) diff -r c9720159b983 -r 9559ba7c80f9 tools/python/xen/xm/labels.py --- a/tools/python/xen/xm/labels.py Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/python/xen/xm/labels.py Tue Jul 17 10:20:21 2007 +0100 @@ -24,6 +24,10 @@ from xen.util.security import ACMError, from xen.util.security import ACMError, err, list_labels, active_policy from xen.util.security import vm_label_re, res_label_re, all_label_re from xen.xm.opts import OptionError +from xen.util.acmpolicy import ACMPolicy +from xen.util import xsconstants +from xen.xm.main import server +from xen.xm import main as xm_main def help(): @@ -48,6 +52,12 @@ def main(argv): else: raise OptionError('Unrecognised option: %s' % arg) + if xm_main.serverType != xm_main.SERVER_XEN_API: + labels(policy, ptype) + else: + labels_xapi(policy, ptype) + +def labels(policy, ptype): if not policy: policy = active_policy if active_policy in ['NULL', 'INACTIVE', 'DEFAULT']: @@ -73,7 +83,30 @@ def main(argv): except: traceback.print_exc(limit = 1) +def labels_xapi(policy, ptype): + policystate = server.xenapi.XSPolicy.get_xspolicy() + if int(policystate['type']) == xsconstants.XS_POLICY_ACM: + acmpol = ACMPolicy(xml=policystate['repr']) + if policy and policy != acmpol.get_name(): + print "Warning: '%s' is not the currently loaded policy." % policy + return labels(policy, ptype) + names1 = [] + names2 = [] + if not ptype or ptype == 'dom' or ptype == 'any': + names1 = acmpol.policy_get_virtualmachinelabel_names() + if ptype == 'res' or ptype == 'any': + names2 = acmpol.policy_get_resourcelabel_names() + if len(names1) > 0: + names = set(names1) + names.union(names2) + else: + names = set(names2) + for n in names: + print n + elif int(policystate['type']) == 0: + print "No policy installed on the system." + else: + print "Unsupported type of policy installed on the system." + if __name__ == '__main__': main(sys.argv) - - diff -r c9720159b983 -r 9559ba7c80f9 tools/python/xen/xm/loadpolicy.py --- a/tools/python/xen/xm/loadpolicy.py Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/python/xen/xm/loadpolicy.py Tue Jul 17 10:20:21 2007 +0100 @@ -22,6 +22,11 @@ import traceback import traceback from xen.util.security import ACMError, err, load_policy from xen.xm.opts import OptionError +from xen.xm import main as xm_main +from xen.util import xsconstants +from xen.xm.activatepolicy import activate_policy +from xen.xm.main import server +from xen.util.acmpolicy import ACMPolicy def help(): return """Load the compiled binary (.bin) policy into the running @@ -30,8 +35,31 @@ def main(argv): def main(argv): if len(argv) != 2: raise OptionError('No policy defined') - - load_policy(argv[1]) + if xm_main.serverType == xm_main.SERVER_XEN_API: + policy = argv[1] + print "This command is deprecated for use with Xen-API " \ + "configuration. Consider using\n'xm activatepolicy'." + policystate = server.xenapi.XSPolicy.get_xspolicy() + if int(policystate['type']) == 0: + print "No policy is installed." + return + + if int(policystate['type']) != xsconstants.XS_POLICY_ACM: + print "Unknown policy type '%s'." % policystate['type'] + return + else: + xml = policystate['repr'] + xs_ref = policystate['xs_ref'] + if not xml: + OptionError("No policy installed on system?") + acmpol = ACMPolicy(xml=xml) + if acmpol.get_name() != policy: + OptionError("Policy installed on system '%s' does not match"\ + " the request policy '%s'" % \ + (acmpol.get_name(), policy)) + activate_policy(xsconstants.XS_INST_LOAD) + else: + load_policy(argv[1]) if __name__ == '__main__': try: diff -r c9720159b983 -r 9559ba7c80f9 tools/python/xen/xm/main.py --- a/tools/python/xen/xm/main.py Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/python/xen/xm/main.py Tue Jul 17 10:20:21 2007 +0100 @@ -50,6 +50,7 @@ from xen.xm.opts import OptionError, Opt from xen.xm.opts import OptionError, Opts, wrap, set_true from xen.xm import console from xen.util.xmlrpcclient import ServerProxy +from xen.util.security import ACMError import XenAPI @@ -171,11 +172,12 @@ SUBCOMMAND_HELP = { # security - 'addlabel' : ('<label> {dom <ConfigFile>|res <resource>} [<policy>]', + 'addlabel' : ('<label> {dom <ConfigFile>|res <resource>|mgt <managed domain>}\n' + ' [<policy>]', 'Add security label to domain.'), - 'rmlabel' : ('{dom <ConfigFile>|res <Resource>}', + 'rmlabel' : ('{dom <ConfigFile>|res <Resource>|mgt<managed domain>}', 'Remove a security label from domain.'), - 'getlabel' : ('{dom <ConfigFile>|res <Resource>}', + 'getlabel' : ('{dom <ConfigFile>|res <Resource>|mgt <managed domain>}', 'Show security label for domain or resource.'), 'dry-run' : ('<ConfigFile>', 'Test if a domain can access its resources.'), @@ -186,6 +188,10 @@ SUBCOMMAND_HELP = { 'loadpolicy' : ('<policy.bin>', 'Load binary policy into hypervisor.'), 'makepolicy' : ('<policy>', 'Build policy and create .bin/.map ' 'files.'), + 'setpolicy' : ('<policytype> <policyfile> [options]', + 'Set the policy of the system.'), + 'getpolicy' : ('[options]', 'Get the policy of the system.'), + 'activatepolicy': ('[options]', 'Activate the xend-managed policy.'), 'labels' : ('[policy] [type=dom|res|any]', 'List <type> labels for (active) policy.'), 'serve' : ('', 'Proxy Xend XMLRPC over stdio.'), @@ -343,6 +349,9 @@ acm_commands = [ "loadpolicy", "cfgbootpolicy", "dumppolicy", + "activatepolicy", + "setpolicy", + "getpolicy", ] all_commands = (domain_commands + host_commands + scheduler_commands + @@ -861,13 +870,13 @@ def parse_doms_info(info): 'up_time' : up_time } - # We're not supporting security stuff just yet via XenAPI - - if serverType != SERVER_XEN_API: - from xen.util import security - parsed_info['seclabel'] = security.get_security_printlabel(info) - else: - parsed_info['seclabel'] = "" + security_label = get_info('security_label', str, '') + tmp = security_label.split(":") + if len(tmp) != 3: + seclabel = "" + else: + seclabel = tmp[2] + parsed_info['seclabel'] = seclabel if serverType == SERVER_XEN_API: parsed_info['mem'] = get_info('memory_actual', int, 0) / 1024 @@ -925,28 +934,26 @@ def xm_brief_list(doms): print format % d def xm_label_list(doms): - print '%-32s %5s %5s %5s %5s %9s %-8s' % \ + print '%-32s %5s %5s %5s %10s %9s %-8s' % \ ('Name', 'ID', 'Mem', 'VCPUs', 'State', 'Time(s)', 'Label') output = [] format = '%(name)-32s %(domid)5s %(mem)5d %(vcpus)5d %(state)10s ' \ '%(cpu_time)8.1f %(seclabel)9s' - if serverType != SERVER_XEN_API: - from xen.util import security + from xen.util import security - for dom in doms: - d = parse_doms_info(dom) - - if security.active_policy not in ['INACTIVE', 'NULL', 'DEFAULT']: - if not d['seclabel']: - d['seclabel'] = 'ERROR' - elif security.active_policy in ['DEFAULT']: - d['seclabel'] = 'DEFAULT' - else: - d['seclabel'] = 'INACTIVE' - - output.append((format % d, d['seclabel'])) + for dom in doms: + d = parse_doms_info(dom) + if security.active_policy not in ['INACTIVE', 'NULL', 'DEFAULT']: + if not d['seclabel']: + d['seclabel'] = 'ERROR' + elif security.active_policy in ['DEFAULT']: + d['seclabel'] = 'DEFAULT' + else: + d['seclabel'] = 'INACTIVE' + + output.append((format % d, d['seclabel'])) #sort by labels output.sort(lambda x,y: cmp( x[1].lower(), y[1].lower())) @@ -1989,16 +1996,24 @@ def xm_block_list(args): % ni) def xm_vtpm_list(args): - xenapi_unsupported() (use_long, params) = arg_check_for_resource_list(args, "vtpm-list") dom = params[0] + + if serverType == SERVER_XEN_API: + vtpm_refs = server.xenapi.VM.get_VTPMs(get_single_vm(dom)) + vtpm_properties = \ + map(server.xenapi.VTPM.get_runtime_properties, vtpm_refs) + devs = map(lambda (handle, properties): [handle, map2sxp(properties)], + zip(range(len(vtpm_properties)), vtpm_properties)) + else: + devs = server.xend.domain.getDeviceSxprs(dom, 'vtpm') + if use_long: - devs = server.xend.domain.getDeviceSxprs(dom, 'vtpm') map(PrettyPrint.prettyprint, devs) else: hdr = 0 - for x in server.xend.domain.getDeviceSxprs(dom, 'vtpm'): + for x in devs: if hdr == 0: print 'Idx BE handle state evt-ch ring-ref BE-path' hdr = 1 @@ -2028,18 +2043,6 @@ def parse_block_configuration(args): ['mode', args[3]]] if len(args) == 5: vbd.append(['backend', args[4]]) - - if serverType != SERVER_XEN_API: - # verify that policy permits attaching this resource - from xen.util import security - - if security.on(): - dominfo = server.xend.domain(dom) - label = security.get_security_printlabel(dominfo) - else: - label = None - - security.res_security_check(args[1], label) return (dom, vbd) @@ -2440,6 +2443,9 @@ IMPORTED_COMMANDS = [ 'getlabel', 'dry-run', 'resources', + 'getpolicy', + 'setpolicy', + 'activatepolicy', ] for c in IMPORTED_COMMANDS: @@ -2563,6 +2569,8 @@ def _run_cmd(cmd, cmd_name, args): print e.usage except XenAPIUnsupportedException, e: err(str(e)) + except ACMError, e: + err(str(e)) except Exception, e: if serverType != SERVER_XEN_API: from xen.util import security diff -r c9720159b983 -r 9559ba7c80f9 tools/python/xen/xm/makepolicy.py --- a/tools/python/xen/xm/makepolicy.py Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/python/xen/xm/makepolicy.py Tue Jul 17 10:20:21 2007 +0100 @@ -20,7 +20,10 @@ import sys import sys import traceback from xen.util.security import ACMError, err, make_policy +from xen.util import xsconstants from xen.xm.opts import OptionError +from xen.xm import main as xm_main +from xen.xm.setpolicy import setpolicy def usage(): print "\nUsage: xm makepolicy <policy>\n" @@ -32,8 +35,13 @@ def main(argv): def main(argv): if len(argv) != 2: raise OptionError('No XML policy file specified') - - make_policy(argv[1]) + if xm_main.serverType == xm_main.SERVER_XEN_API: + print "This command is deprecated for use with Xen-API " \ + "configuration. Consider using\n'xm setpolicy'." + setpolicy(xsconstants.ACM_POLICY_ID, argv[1], + xsconstants.XS_INST_LOAD, True) + else: + make_policy(argv[1]) if __name__ == '__main__': try: @@ -41,5 +49,3 @@ if __name__ == '__main__': except Exception, e: sys.stderr.write('Error: %s\n' % str(e)) sys.exit(-1) - - diff -r c9720159b983 -r 9559ba7c80f9 tools/python/xen/xm/resources.py --- a/tools/python/xen/xm/resources.py Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/python/xen/xm/resources.py Tue Jul 17 10:20:21 2007 +0100 @@ -21,7 +21,10 @@ import sys import sys from xen.util import dictio from xen.util import security +from xen.util import xsconstants from xen.xm.opts import OptionError +from xen.xm import main as xm_main +from xen.xm.main import server def help(): return """ @@ -32,20 +35,32 @@ def print_resource_data(access_control): """Prints out a resource dictionary to stdout """ for resource in access_control: - (policy, label) = access_control[resource] + tmp = access_control[resource] + if len(tmp) == 2: + policytype = xsconstants.ACM_POLICY_ID + (policy, label) = access_control[resource] + elif len(tmp) == 3: + policytype, policy, label = access_control[resource] print resource - print " policy: "+policy - print " label: "+label + print " type: "+ policytype + print " policy: "+ policy + print " label: "+ label def main (argv): if len(argv) > 1: raise OptionError("No arguments required") - - try: - filename = security.res_label_filename - access_control = dictio.dict_read("resources", filename) - except: - raise OptionError("Resource file not found") + + if xm_main.serverType == xm_main.SERVER_XEN_API: + access_control = server.xenapi.XSPolicy.get_labeled_resources() + for key, value in access_control.items(): + access_control[key] = tuple(value.split(':')) + else: + try: + filename = security.res_label_filename + access_control = dictio.dict_read("resources", filename) + print access_control + except: + raise OptionError("Resource file not found") print_resource_data(access_control) diff -r c9720159b983 -r 9559ba7c80f9 tools/python/xen/xm/rmlabel.py --- a/tools/python/xen/xm/rmlabel.py Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/python/xen/xm/rmlabel.py Tue Jul 17 10:20:21 2007 +0100 @@ -22,35 +22,52 @@ from xen.util import dictio from xen.util import dictio from xen.util import security from xen.xm.opts import OptionError +from xen.xm import main as xm_main +from xen.xm.main import server def help(): return """ Example: xm rmlabel dom <configfile> xm rmlabel res <resource> + xm rmlabel mgt <domain name> This program removes an acm_label entry from the 'configfile' - for a domain or from the global resource label file for a - resource. If the label does not exist for the given domain or - resource, then rmlabel fails.""" + for a domain, from a Xend-managed domain, from the global resource label + file for a resource or from the virtual network interface of a Xend-managed + domain. If the label does not exist for the given domain or resource, then + rmlabel fails.""" def rm_resource_label(resource): """Removes a resource label from the global resource label file. """ + # Try Xen-API first if configured to use it + if xm_main.serverType == xm_main.SERVER_XEN_API: + try: + oldlabel = server.xenapi.XSPolicy.get_resource_label(resource) + if oldlabel != "": + server.xenapi.XSPolicy.set_resource_label(resource,"", + oldlabel) + else: + raise security.ACMError("Resource not labeled") + except Exception, e: + print "Could not remove label from resource: %s" % e + return + #build canonical resource name resource = security.unify_resname(resource) # read in the resource file - file = security.res_label_filename + fil = security.res_label_filename try: - access_control = dictio.dict_read("resources", file) + access_control = dictio.dict_read("resources", fil) except: raise security.ACMError("Resource file not found, cannot remove label!") # remove the entry and update file if access_control.has_key(resource): del access_control[resource] - dictio.dict_write(access_control, "resources", file) + dictio.dict_write(access_control, "resources", fil) else: raise security.ACMError("Resource not labeled") @@ -58,15 +75,15 @@ def rm_domain_label(configfile): def rm_domain_label(configfile): # open the domain config file fd = None - file = None + fil = None if configfile[0] == '/': - file = configfile - fd = open(file, "rb") + fil = configfile + fd = open(fil, "rb") else: for prefix in [".", "/etc/xen"]: - file = prefix + "/" + configfile - if os.path.isfile(file): - fd = open(file, "rb") + fil = prefix + "/" + configfile + if os.path.isfile(fil): + fd = open(fil, "rb") break if not fd: raise OptionError("Configuration file '%s' not found." % configfile) @@ -93,9 +110,24 @@ def rm_domain_label(configfile): raise security.ACMError('Domain not labeled') # write the data back out to the file - fd = open(file, "wb") + fd = open(fil, "wb") fd.writelines(file_contents) fd.close() + +def rm_domain_label_xapi(domainname): + if xm_main.serverType != xm_main.SERVER_XEN_API: + raise OptionError('Need to be configure for using xen-api.') + uuids = server.xenapi.VM.get_by_name_label(domainname) + if len(uuids) == 0: + raise OptionError('A VM with that name does not exist.') + if len(uuids) != 1: + raise OptionError('Too many domains with the same name.') + uuid = uuids[0] + try: + old_lab = server.xenapi.VM.get_security_label(uuid) + server.xenapi.VM.set_security_label(uuid, "", old_lab) + except Exception, e: + print('Could not remove label from domain: %s' % e) def main (argv): @@ -103,12 +135,15 @@ def main (argv): if len(argv) != 3: raise OptionError('Requires 2 arguments') - if argv[1].lower() not in ('dom', 'res'): + if argv[1].lower() not in ('dom', 'mgt', 'res'): raise OptionError('Unrecognised type argument: %s' % argv[1]) if argv[1].lower() == "dom": configfile = argv[2] rm_domain_label(configfile) + elif argv[1].lower() == "mgt": + domain = argv[2] + rm_domain_label_xapi(domain) elif argv[1].lower() == "res": resource = argv[2] rm_resource_label(resource) @@ -119,5 +154,3 @@ if __name__ == '__main__': except Exception, e: sys.stderr.write('Error: %s\n' % str(e)) sys.exit(-1) - - diff -r c9720159b983 -r 9559ba7c80f9 tools/python/xen/xm/setpolicy.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/python/xen/xm/setpolicy.py Tue Jul 17 10:20:21 2007 +0100 @@ -0,0 +1,117 @@ +#============================================================================ +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#============================================================================ +# Copyright (C) 2007 International Business Machines Corp. +# Author: Stefan Berger <stefanb@xxxxxxxxxx> +#============================================================================ + +"""Get the managed policy of the system. +""" + +import base64 +import struct +import sys +import string +from xen.util import xsconstants +from xen.xm.opts import OptionError +from xen.util.security import policy_dir_prefix +from xen.xm import main as xm_main +from xen.xm.main import server + +def help(): + return """ + Usage: xm setpolicy <policytype> <policy> [options] + + Set the policy managed by xend. + + The only policytype that is currently supported is 'ACM'. + + The following options are defined + --load Load the policy immediately + --boot Have the system load the policy during boot + """ + +def setpolicy(policytype, policy_name, flags, overwrite): + if xm_main.serverType != xm_main.SERVER_XEN_API: + raise OptionError('xm needs to be configured to use the xen-api.') + if policytype != xsconstants.ACM_POLICY_ID: + raise OptionError("Unsupported policytype '%s'." % policytype) + else: + xs_type = xsconstants.XS_POLICY_ACM + + policy_file = policy_dir_prefix + "/" + \ + string.join(string.split(policy_name, "."), "/") + policy_file += "-security_policy.xml" + + try: + f = open(policy_file,"r") + xml = f.read(-1) + f.close() + except: + raise OptionError("Not a valid policy file") + + try: + policystate = server.xenapi.XSPolicy.set_xspolicy(xs_type, + xml, + flags, + overwrite) + except Exception, e: + print "An error occurred setting the policy: %s" % str(e) + return + xserr = int(policystate['xserr']) + if xserr != 0: + print "An error occurred trying to set the policy: %s" % \ + xsconstants.xserr2string(abs(xserr)) + errors = policystate['errors'] + if len(errors) > 0: + print "Hypervisor reported errors:" + err = base64.b64decode(errors) + i = 0 + while i + 7 < len(err): + code, data = struct.unpack("!ii", errors[i:i+8]) + print "(0x%08x, 0x%08x)" % (code, data) + i += 8 + else: + print "Successfully set the new policy." + + +def main(argv): + if len(argv) < 3: + raise OptionError("Need at least 3 arguments.") + + if "-?" in argv: + help() + return + + policytype = argv[1] + policy_name = argv[2] + + flags = 0 + if '--load' in argv: + flags |= xsconstants.XS_INST_LOAD + if '--boot' in argv: + flags |= xsconstants.XS_INST_BOOT + + overwrite = True + if '--nooverwrite' in argv: + overwrite = False + + setpolicy(policytype, policy_name, flags, overwrite) + +if __name__ == '__main__': + try: + main(sys.argv) + except Exception, e: + sys.stderr.write('Error: %s\n' % str(e)) + sys.exit(-1) diff -r c9720159b983 -r 9559ba7c80f9 tools/python/xen/xm/xenapi_create.py --- a/tools/python/xen/xm/xenapi_create.py Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/python/xen/xm/xenapi_create.py Tue Jul 17 10:20:21 2007 +0100 @@ -25,6 +25,7 @@ from xen.xend.XendAPIConstants import XE from xen.xend.XendAPIConstants import XEN_API_ON_NORMAL_EXIT, \ XEN_API_ON_CRASH_BEHAVIOUR from xen.xm.opts import OptionError +from xen.util import xsconstants import sys import os @@ -308,6 +309,12 @@ class xenapi_create: "" } + if vm.attributes.has_key("security_label"): + vm_record.update({ + "security_label": + vm.attributes["security_label"].value + }) + if len(vm.getElementsByTagName("pv")) > 0: vm_record.update({ "PV_bootloader": @@ -348,6 +355,12 @@ class xenapi_create: self.create_vifs(vm_ref, vifs, networks) + # Now create vtpms + + vtpms = vm.getElementsByTagName("vtpm") + + self.create_vtpms(vm_ref, vtpms) + # Now create consoles consoles = vm.getElementsByTagName("console") @@ -441,6 +454,21 @@ class xenapi_create: self._network_refs = server.xenapi.network.get_all() return self._network_refs.pop(0) + def create_vtpms(self, vm_ref, vtpms): + if len(vtpms) > 1: + vtpms = [ vtpms[0] ] + log(DEBUG, "create_vtpms") + return map(lambda vtpm: self.create_vtpm(vm_ref, vtpm), vtpms) + + def create_vtpm(self, vm_ref, vtpm): + vtpm_record = { + "VM": + vm_ref, + "backend": + vtpm.attributes["backend"].value + } + return server.xenapi.VTPM.create(vtpm_record) + def create_consoles(self, vm_ref, consoles): log(DEBUG, "create_consoles") return map(lambda console: self.create_console(vm_ref, console), @@ -482,6 +510,10 @@ class sxp2xml: vifs_sxp = map(lambda x: x[1], [device for device in devices if device[1][0] == "vif"]) + + vtpms_sxp = map(lambda x: x[1], [device for device in devices + if device[1][0] == "vtpm"]) + # Create XML Document impl = getDOMImplementation() @@ -530,6 +562,14 @@ class sxp2xml: = str(get_child_by_name(config, "vcpus", 1)) vm.attributes["vcpus_at_startup"] \ = str(get_child_by_name(config, "vcpus", 1)) + + sec_data = get_child_by_name(config, "security") + if sec_data: + try : + vm.attributes['security_label'] = \ + "%s:%s:%s" % (xsconstants.ACM_POLICY_ID, sec_data[0][1][1],sec_data[0][2][1]) + except Exception, e: + raise "Invalid security data format: %s" % str(sec_data) # Make the name tag @@ -601,6 +641,12 @@ class sxp2xml: map(vm.appendChild, vifs) + # And now the vTPMs + + vtpms = map(lambda vtpm: self.extract_vtpm(vtpm, document), vtpms_sxp) + + map(vm.appendChild, vtpms) + # Last but not least the consoles... consoles = self.extract_consoles(image, document) @@ -707,6 +753,15 @@ class sxp2xml: = get_child_by_name(vif_sxp, "bridge") return vif + + def extract_vtpm(self, vtpm_sxp, document): + + vtpm = document.createElement("vtpm") + + vtpm.attributes["backend"] \ + = get_child_by_name(vtpm_sxp, "backend", "0") + + return vtpm _eths = -1 diff -r c9720159b983 -r 9559ba7c80f9 tools/security/policies/security_policy.xsd --- a/tools/security/policies/security_policy.xsd Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/security/policies/security_policy.xsd Tue Jul 17 10:20:21 2007 +0100 @@ -99,7 +99,7 @@ <xsd:sequence> <xsd:element name="Name" type="NameWithFrom"></xsd:element> <xsd:element ref="SimpleTypeEnforcementTypes" minOccurs="0" maxOccurs="unbounded" /> - <xsd:element name="ChineseWallTypes" type="SingleChineseWallType" /> + <xsd:element ref="ChineseWallTypes" minOccurs="0" maxOccurs="unbounded" /> </xsd:sequence> </xsd:complexType> </xsd:element> @@ -143,9 +143,4 @@ <xsd:element maxOccurs="1" minOccurs="1" ref="Type" /> </xsd:sequence> </xsd:complexType> - <xsd:complexType name="SingleChineseWallType"> - <xsd:sequence> - <xsd:element maxOccurs="1" minOccurs="1" ref="Type" /> - </xsd:sequence> - </xsd:complexType> </xsd:schema> diff -r c9720159b983 -r 9559ba7c80f9 tools/vtpm_manager/util/hashtable_itr.c --- a/tools/vtpm_manager/util/hashtable_itr.c Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/vtpm_manager/util/hashtable_itr.c Tue Jul 17 10:20:21 2007 +0100 @@ -225,7 +225,7 @@ hashtable_iterator_search(struct hashtab egress: #ifdef HASHTABLE_THREADED - pthread_mutex_lock(&h->mutex); -#endif - return ret; -} + pthread_mutex_unlock(&h->mutex); +#endif + return ret; +} diff -r c9720159b983 -r 9559ba7c80f9 tools/xenstore/xsls.c --- a/tools/xenstore/xsls.c Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/xenstore/xsls.c Tue Jul 17 10:20:21 2007 +0100 @@ -8,6 +8,7 @@ #include <sys/ioctl.h> #include <termios.h> +#define STRING_MAX PATH_MAX static int max_width = 80; static int desired_width = 60; @@ -19,7 +20,8 @@ void print_dir(struct xs_handle *h, char void print_dir(struct xs_handle *h, char *path, int cur_depth, int show_perms) { char **e; - char newpath[512], *val; + char newpath[STRING_MAX], *val; + int newpath_len; int i; unsigned int num, len; @@ -33,13 +35,26 @@ void print_dir(struct xs_handle *h, char unsigned int nperms; int linewid; - for (linewid=0; linewid<cur_depth; linewid++) putchar(' '); + /* Print indent and path basename */ + for (linewid=0; linewid<cur_depth; linewid++) { + putchar(' '); + } linewid += printf("%.*s", (int) (max_width - TAG_LEN - linewid), e[i]); - sprintf(newpath, "%s%s%s", path, + + /* Compose fullpath and fetch value */ + newpath_len = snprintf(newpath, sizeof(newpath), "%s%s%s", path, path[strlen(path)-1] == '/' ? "" : "/", e[i]); - val = xs_read(h, XBT_NULL, newpath, &len); + if ( newpath_len < sizeof(newpath) ) { + val = xs_read(h, XBT_NULL, newpath, &len); + } + else { + /* Path was truncated and thus invalid */ + val = NULL; + } + + /* Print value */ if (val == NULL) { printf(":\n"); } @@ -88,7 +103,7 @@ void print_dir(struct xs_handle *h, char void usage(int argc, char *argv[]) { - fprintf(stderr, "Usage: %s [-p] [path]\n", argv[0]); + fprintf(stderr, "Usage: %s [-w] [-p] [path]\n", argv[0]); } int main(int argc, char *argv[]) @@ -104,11 +119,14 @@ int main(int argc, char *argv[]) if (!ret) max_width = ws.ws_col - PAD; - while (0 < (c = getopt(argc, argv, "ps"))) { + while (0 < (c = getopt(argc, argv, "psw"))) { switch (c) { + case 'w': + max_width= STRING_MAX - PAD; + desired_width = 0; + break; case 'p': show_perm = 1; - max_width -= 16; break; case 's': socket = 1; @@ -121,6 +139,11 @@ int main(int argc, char *argv[]) } } + /* Adjust the width here to avoid argument order dependency */ + if ( show_perm ) { + max_width -= 16; + } + xsh = socket ? xs_daemon_open() : xs_domain_open(); if (xsh == NULL) err(1, socket ? "xs_daemon_open" : "xs_domain_open"); diff -r c9720159b983 -r 9559ba7c80f9 tools/xentrace/xenctx.c --- a/tools/xentrace/xenctx.c Mon Jul 16 14:20:16 2007 -0500 +++ b/tools/xentrace/xenctx.c Tue Jul 17 10:20:21 2007 +0100 @@ -47,6 +47,13 @@ int stack_trace = 0; #elif defined (__ia64__) /* On ia64, we can't translate virtual address to physical address. */ #define NO_TRANSLATION + +/* Which registers should be displayed. */ +int disp_cr_regs; +int disp_ar_regs; +int disp_br_regs; +int disp_bank_regs; +int disp_tlb; #endif struct symbol { @@ -287,12 +294,12 @@ void print_ctx(vcpu_guest_context_t *ctx #define ITIR_PS_MAX 28 #define RR_RID_SHIFT 8 #define RR_RID_MASK 0xffffff - -void print_ctx(vcpu_guest_context_t *ctx1) -{ - struct vcpu_guest_context_regs *regs = &ctx1->regs; - struct vcpu_tr_regs *tr = &ctx1->regs.tr; - int i, ps_val, ma_val; +#define PSR_BN (1UL << 44) +#define CFM_SOF_MASK 0x3f + +static void print_tr(int i, const struct ia64_tr_entry *tr) +{ + int ps_val, ma_val; unsigned long pa; static const char ps[][5] = {" 4K", " 8K", " 16K", " ", @@ -303,104 +310,204 @@ void print_ctx(vcpu_guest_context_t *ctx static const char ma[][4] = {"WB ", " ", " ", " ", "UC ", "UCE", "WC ", "Nat"}; - printf(" ip: %016lx ", regs->ip); + ps_val = tr->itir >> ITIR_PS_SHIFT & ITIR_PS_MASK; + ma_val = tr->pte >> PTE_MA_SHIFT & PTE_MA_MASK; + pa = (tr->pte >> PTE_PPN_SHIFT & PTE_PPN_MASK) << PTE_PPN_SHIFT; + pa = (pa >> ps_val) << ps_val; + printf(" [%d] %ld %06lx %016lx %013lx %02x %s %ld %ld %ld %ld " + "%ld %d %s %06lx\n", i, + tr->pte >> PTE_P_SHIFT & PTE_P_MASK, + tr->rid >> RR_RID_SHIFT & RR_RID_MASK, + tr->vadr, pa, ps_val, + ((ps_val >= ITIR_PS_MIN && ps_val <= ITIR_PS_MAX) ? + ps[ps_val - ITIR_PS_MIN] : " "), + tr->pte >> PTE_ED_SHIFT & PTE_ED_MASK, + tr->pte >> PTE_PL_SHIFT & PTE_PL_MASK, + tr->pte >> PTE_AR_SHIFT & PTE_AR_MASK, + tr->pte >> PTE_A_SHIFT & PTE_A_MASK, + tr->pte >> PTE_D_SHIFT & PTE_D_MASK, + ma_val, ma[ma_val], + tr->itir >> ITIR_KEY_SHIFT & ITIR_KEY_MASK); +} + +void print_ctx(vcpu_guest_context_t *ctx) +{ + struct vcpu_guest_context_regs *regs = &ctx->regs; + struct vcpu_tr_regs *tr = &ctx->regs.tr; + int i; + unsigned int rbs_size, cfm_sof; + + printf(" ip: %016lx ", regs->ip); print_symbol(regs->ip); printf("\n"); - printf(" psr: %016lx ", regs->psr); - printf(" b0: %016lx\n", regs->b[0]); - printf(" b6: %016lx ", regs->b[6]); - printf(" b7: %016lx\n", regs->b[7]); - printf(" cfm: %016lx ", regs->cfm); - printf(" ar.unat: %016lx\n", regs->ar.unat); - printf(" ar.pfs: %016lx ", regs->ar.pfs); - printf(" ar.rsc: %016lx\n", regs->ar.rsc); - printf(" ar.rnat: %016lx ", regs->ar.rnat); - printf(" ar.bspstore: %016lx\n", regs->ar.bspstore); - printf(" ar.fpsr: %016lx ", regs->ar.fpsr); - printf(" event_callback_ip: %016lx\n", ctx1->event_callback_ip); - printf(" pr: %016lx ", regs->pr); - /* printf(" loadrs: %016lx\n", regs->loadrs); */ - printf(" iva: %016lx\n", regs->cr.iva); - printf(" dcr: %016lx\n", regs->cr.dcr); - - printf("\n"); - printf(" r1: %016lx\n", regs->r[1]); + printf(" psr: %016lx ", regs->psr); + printf(" cfm: %016lx ", regs->cfm); + printf(" pr: %016lx\n", regs->pr); + + if (disp_br_regs) { + printf(" b0: %016lx ", regs->b[0]); + printf(" b1: %016lx ", regs->b[1]); + printf(" b2: %016lx\n", regs->b[2]); + printf(" b3: %016lx ", regs->b[3]); + printf(" b4: %016lx ", regs->b[4]); + printf(" b5: %016lx\n", regs->b[5]); + printf(" b6: %016lx ", regs->b[6]); + printf(" b7: %016lx\n", regs->b[7]); + } else { + printf(" b0: %016lx\n", regs->b[0]); + } + + if (disp_cr_regs) { + printf ("\n" + " CR:\n"); + printf(" dcr: %016lx ", regs->cr.dcr); + printf(" itm: %016lx ", regs->cr.itm); + printf(" iva: %016lx\n", regs->cr.iva); + printf(" pta: %016lx ", regs->cr.pta); + printf(" ipsr: %016lx ", regs->cr.ipsr); + printf(" isr: %016lx\n", regs->cr.isr); + printf(" iip: %016lx ", regs->cr.iip); + printf(" ifa: %016lx ", regs->cr.ifa); + printf(" itir: %016lx\n", regs->cr.itir); + printf(" iipa: %016lx ", regs->cr.iipa); + printf(" ifs: %016lx ", regs->cr.ifs); + printf(" iim: %016lx\n", regs->cr.iim); + printf(" iha: %016lx ", regs->cr.iha); + printf(" lid: %016lx ", regs->cr.lid); + printf(" ivr: %016lx\n", regs->cr.ivr); + printf(" tpr: %016lx ", regs->cr.tpr); + printf(" eoi: %016lx ", regs->cr.eoi); + printf(" irr0: %016lx\n", regs->cr.irr[0]); + printf(" irr1: %016lx ", regs->cr.irr[1]); + printf(" irr2: %016lx ", regs->cr.irr[2]); + printf(" irr3: %016lx\n", regs->cr.irr[3]); + printf(" itv: %016lx ", regs->cr.itv); + printf(" pmv: %016lx ", regs->cr.pmv); + printf(" cmcv: %016lx\n", regs->cr.cmcv); + printf(" lrr0: %016lx ", regs->cr.lrr0); + printf(" lrr1: %016lx ", regs->cr.lrr1); + printf(" ev_cb:%016lx\n", ctx->event_callback_ip); + + } + if (disp_ar_regs) { + printf ("\n" + " AR:\n"); + printf(" kr0: %016lx ", regs->ar.kr[0]); + printf(" kr1: %016lx ", regs->ar.kr[1]); + printf(" kr2: %016lx\n", regs->ar.kr[2]); + printf(" kr3: %016lx ", regs->ar.kr[3]); + printf(" kr4: %016lx ", regs->ar.kr[4]); + printf(" kr5: %016lx\n", regs->ar.kr[5]); + printf(" kr6: %016lx ", regs->ar.kr[6]); + printf(" kr7: %016lx ", regs->ar.kr[7]); + printf(" rsc: %016lx\n", regs->ar.rsc); + printf(" bsp: %016lx ", regs->ar.bsp); + printf(" bsps: %016lx ", regs->ar.bspstore); + printf(" rnat: %016lx\n", regs->ar.rnat); + printf(" csd: %016lx ", regs->ar.csd); + printf(" ccv: %016lx ", regs->ar.ccv); + printf(" unat: %016lx\n", regs->ar.unat); + printf(" fpsr: %016lx ", regs->ar.fpsr); + printf(" itc: %016lx\n", regs->ar.itc); + printf(" pfs: %016lx ", regs->ar.pfs); + printf(" lc: %016lx ", regs->ar.lc); + printf(" ec: %016lx\n", regs->ar.ec); + } + printf("\n"); + printf(" r1: %016lx ", regs->r[1]); printf(" r2: %016lx ", regs->r[2]); printf(" r3: %016lx\n", regs->r[3]); printf(" r4: %016lx ", regs->r[4]); - printf(" r5: %016lx\n", regs->r[5]); - printf(" r6: %016lx ", regs->r[6]); - printf(" r7: %016lx\n", regs->r[7]); + printf(" r5: %016lx ", regs->r[5]); + printf(" r6: %016lx\n", regs->r[6]); + printf(" r7: %016lx ", regs->r[7]); printf(" r8: %016lx ", regs->r[8]); printf(" r9: %016lx\n", regs->r[9]); printf(" r10: %016lx ", regs->r[10]); - printf(" r11: %016lx\n", regs->r[11]); - printf(" sp: %016lx ", regs->r[12]); - printf(" tp: %016lx\n", regs->r[13]); + printf(" r11: %016lx ", regs->r[11]); + printf(" sp: %016lx\n", regs->r[12]); + printf(" tp: %016lx ", regs->r[13]); printf(" r14: %016lx ", regs->r[14]); printf(" r15: %016lx\n", regs->r[15]); - printf(" r16: %016lx ", regs->r[16]); - printf(" r17: %016lx\n", regs->r[17]); - printf(" r18: %016lx ", regs->r[18]); - printf(" r19: %016lx\n", regs->r[19]); - printf(" r20: %016lx ", regs->r[20]); - printf(" r21: %016lx\n", regs->r[21]); - printf(" r22: %016lx ", regs->r[22]); - printf(" r23: %016lx\n", regs->r[23]); - printf(" r24: %016lx ", regs->r[24]); - printf(" r25: %016lx\n", regs->r[25]); - printf(" r26: %016lx ", regs->r[26]); - printf(" r27: %016lx\n", regs->r[27]); - printf(" r28: %016lx ", regs->r[28]); - printf(" r29: %016lx\n", regs->r[29]); - printf(" r30: %016lx ", regs->r[30]); - printf(" r31: %016lx\n", regs->r[31]); - - printf("\n itr: P rid va pa ps ed pl " - "ar a d ma key\n"); - for (i = 0; i < 8; i++) { - ps_val = tr->itrs[i].itir >> ITIR_PS_SHIFT & ITIR_PS_MASK; - ma_val = tr->itrs[i].pte >> PTE_MA_SHIFT & PTE_MA_MASK; - pa = (tr->itrs[i].pte >> PTE_PPN_SHIFT & PTE_PPN_MASK) << - PTE_PPN_SHIFT; - pa = (pa >> ps_val) << ps_val; - printf(" [%d] %ld %06lx %016lx %013lx %02x %s %ld %ld %ld %ld " - "%ld %d %s %06lx\n", i, - tr->itrs[i].pte >> PTE_P_SHIFT & PTE_P_MASK, - tr->itrs[i].rid >> RR_RID_SHIFT & RR_RID_MASK, - tr->itrs[i].vadr, pa, ps_val, - ((ps_val >= ITIR_PS_MIN && ps_val <= ITIR_PS_MAX) ? - ps[ps_val - ITIR_PS_MIN] : " "), - tr->itrs[i].pte >> PTE_ED_SHIFT & PTE_ED_MASK, - tr->itrs[i].pte >> PTE_PL_SHIFT & PTE_PL_MASK, - tr->itrs[i].pte >> PTE_AR_SHIFT & PTE_AR_MASK, - tr->itrs[i].pte >> PTE_A_SHIFT & PTE_A_MASK, - tr->itrs[i].pte >> PTE_D_SHIFT & PTE_D_MASK, - ma_val, ma[ma_val], - tr->itrs[i].itir >> ITIR_KEY_SHIFT & ITIR_KEY_MASK); - } - printf("\n dtr: P rid va pa ps ed pl " - "ar a d ma key\n"); - for (i = 0; i < 8; i++) { - ps_val = tr->dtrs[i].itir >> ITIR_PS_SHIFT & ITIR_PS_MASK; - ma_val = tr->dtrs[i].pte >> PTE_MA_SHIFT & PTE_MA_MASK; - pa = (tr->dtrs[i].pte >> PTE_PPN_SHIFT & PTE_PPN_MASK) << - PTE_PPN_SHIFT; - pa = (pa >> ps_val) << ps_val; - printf(" [%d] %ld %06lx %016lx %013lx %02x %s %ld %ld %ld %ld " - "%ld %d %s %06lx\n", i, - tr->dtrs[i].pte >> PTE_P_SHIFT & PTE_P_MASK, - tr->dtrs[i].rid >> RR_RID_SHIFT & RR_RID_MASK, - tr->dtrs[i].vadr, pa, ps_val, - ((ps_val >= ITIR_PS_MIN && ps_val <= ITIR_PS_MAX) ? - ps[ps_val - ITIR_PS_MIN] : " "), - tr->dtrs[i].pte >> PTE_ED_SHIFT & PTE_ED_MASK, - tr->dtrs[i].pte >> PTE_PL_SHIFT & PTE_PL_MASK, - tr->dtrs[i].pte >> PTE_AR_SHIFT & PTE_AR_MASK, - tr->dtrs[i].pte >> PTE_A_SHIFT & PTE_A_MASK, - tr->dtrs[i].pte >> PTE_D_SHIFT & PTE_D_MASK, - ma_val, ma[ma_val], - tr->dtrs[i].itir >> ITIR_KEY_SHIFT & ITIR_KEY_MASK); + if (disp_bank_regs) { + printf(" Bank %d (current) Bank %d\n", + (regs->psr & PSR_BN) ? 1 : 0, (regs->psr & PSR_BN) ? 0 : 1); + printf ("16:%016lx ", regs->r[16]); + printf ("17:%016lx ", regs->r[17]); + printf ("16:%016lx ", regs->bank[0]); + printf ("17:%016lx\n", regs->bank[1]); + printf ("18:%016lx ", regs->r[18]); + printf ("19:%016lx ", regs->r[19]); + printf ("18:%016lx ", regs->bank[2]); + printf ("19:%016lx\n", regs->bank[3]); + printf ("20:%016lx ", regs->r[20]); + printf ("21:%016lx ", regs->r[21]); + printf ("20:%016lx ", regs->bank[4]); + printf ("21:%016lx\n", regs->bank[5]); + printf ("22:%016lx ", regs->r[22]); + printf ("23:%016lx ", regs->r[23]); + printf ("22:%016lx ", regs->bank[6]); + printf ("23:%016lx\n", regs->bank[7]); + printf ("24:%016lx ", regs->r[24]); + printf ("25:%016lx ", regs->r[25]); + printf ("24:%016lx ", regs->bank[8]); + printf ("25:%016lx\n", regs->bank[9]); + printf ("26:%016lx ", regs->r[26]); + printf ("27:%016lx ", regs->r[27]); + printf ("26:%016lx ", regs->bank[10]); + printf ("27:%016lx\n", regs->bank[11]); + printf ("28:%016lx ", regs->r[28]); + printf ("29:%016lx ", regs->r[29]); + printf ("28:%016lx ", regs->bank[12]); + printf ("29:%016lx\n", regs->bank[13]); + printf ("30:%016lx ", regs->r[30]); + printf ("31:%016lx ", regs->r[31]); + printf ("30:%016lx ", regs->bank[14]); + printf ("31:%016lx\n", regs->bank[15]); + } else { + printf(" r16: %016lx ", regs->r[16]); + printf(" r17: %016lx ", regs->r[17]); + printf(" r18: %016lx\n", regs->r[18]); + printf(" r19: %016lx ", regs->r[19]); + printf(" r20: %016lx ", regs->r[20]); + printf(" r21: %016lx\n", regs->r[21]); + printf(" r22: %016lx ", regs->r[22]); + printf(" r23: %016lx ", regs->r[23]); + printf(" r24: %016lx\n", regs->r[24]); + printf(" r25: %016lx ", regs->r[25]); + printf(" r26: %016lx ", regs->r[26]); + printf(" r27: %016lx\n", regs->r[27]); + printf(" r28: %016lx ", regs->r[28]); + printf(" r29: %016lx ", regs->r[29]); + printf(" r30: %016lx\n", regs->r[30]); + printf(" r31: %016lx\n", regs->r[31]); + } + + printf("\n"); + rbs_size = (regs->ar.bsp - regs->ar.bspstore) / 8; + cfm_sof = (regs->cfm & CFM_SOF_MASK); + for (i = 0; i < cfm_sof; i++) { + int off = cfm_sof - i; + unsigned int rbs_off = + (((62 - ((rbs_size + regs->rbs_voff) % 64) + off)) / 63) + off; + if (rbs_off > rbs_size) + break; + printf(" r%02d: %016lx%s", 32 + i, + regs->rbs[rbs_size - rbs_off], + (i % 3) != 2 ? " " : "\n"); + } + if ((i % 3) != 0) + printf ("\n"); + + if (disp_tlb) { + printf("\n itr: P rid va pa ps ed pl " + "ar a d ma key\n"); + for (i = 0; i < 8; i++) + print_tr(i, &tr->itrs[i]); + printf("\n dtr: P rid va pa ps ed pl " + "ar a d ma key\n"); + for (i = 0; i < 8; i++) + print_tr(i, &tr->dtrs[i]); } } #endif @@ -526,9 +633,16 @@ void dump_ctx(int vcpu) { int ret; vcpu_guest_context_t ctx; + xc_dominfo_t dominfo; xc_handle = xc_interface_open(); /* for accessing control interface */ + ret = xc_domain_getinfo(xc_handle, domid, 1, &dominfo); + if (ret < 0) { + perror("xc_domain_getinfo"); + exit(-1); + } + ret = xc_domain_pause(xc_handle, domid); if (ret < 0) { perror("xc_domain_pause"); @@ -537,7 +651,8 @@ void dump_ctx(int vcpu) ret = xc_vcpu_getcontext(xc_handle, domid, vcpu, &ctx); if (ret < 0) { - xc_domain_unpause(xc_handle, domid); + if (!dominfo.paused) + xc_domain_unpause(xc_handle, domid); perror("xc_vcpu_getcontext"); exit(-1); } @@ -548,10 +663,12 @@ void dump_ctx(int vcpu) print_stack(&ctx, vcpu); #endif - ret = xc_domain_unpause(xc_handle, domid); - if (ret < 0) { - perror("xc_domain_unpause"); - exit(-1); + if (!dominfo.paused) { + ret = xc_domain_unpause(xc_handle, domid); + if (ret < 0) { + perror("xc_domain_unpause"); + exit(-1); + } } xc_interface_close(xc_handle); @@ -574,16 +691,28 @@ void usage(void) printf(" -s SYMTAB, --symbol-table=SYMTAB\n"); printf(" read symbol table from SYMTAB.\n"); printf(" --stack-trace print a complete stack trace.\n"); +#ifdef __ia64__ + printf(" -r LIST, --regs=LIST display more registers.\n"); + printf(" -a --all same as --regs=tlb,cr,ar,br,bk\n"); +#endif } int main(int argc, char **argv) { int ch; - const char *sopts = "fs:h"; - const struct option lopts[] = { + static const char *sopts = "fs:h" +#ifdef __ia64__ + "ar:" +#endif + ; + static const struct option lopts[] = { {"stack-trace", 0, NULL, 'S'}, {"symbol-table", 1, NULL, 's'}, {"frame-pointers", 0, NULL, 'f'}, +#ifdef __ia64__ + {"regs", 1, NULL, 'r'}, + {"all", 0, NULL, 'a'}, +#endif {"help", 0, NULL, 'h'}, {0, 0, 0, 0} }; @@ -602,6 +731,39 @@ int main(int argc, char **argv) case 'S': stack_trace = 1; break; +#ifdef __ia64__ + case 'r': + { + char *r; + + r = strtok(optarg, ","); + while (r) { + if (strcmp (r, "cr") == 0) + disp_cr_regs = 1; + else if (strcmp (r, "ar") == 0) + disp_ar_regs = 1; + else if (strcmp (r, "br") == 0) + disp_br_regs = 1; + else if (strcmp (r, "bk") == 0) + disp_bank_regs = 1; + else if (strcmp (r, "tlb") == 0) + disp_tlb = 1; + else { + fprintf(stderr,"unknown register set %s\n", r); + exit(-1); + } + r = strtok(NULL, "'"); + } + } + break; + case 'a': + disp_cr_regs = 1; + disp_ar_regs = 1; + disp_br_regs = 1; + disp_bank_regs = 1; + disp_tlb = 1; + break; +#endif case 'h': usage(); exit(-1); diff -r c9720159b983 -r 9559ba7c80f9 unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h --- a/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h Mon Jul 16 14:20:16 2007 -0500 +++ b/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h Tue Jul 17 10:20:21 2007 +0100 @@ -107,4 +107,13 @@ extern char *kasprintf(gfp_t gfp, const #define __supported_pte_mask ((maddr_t)0) #endif +#if defined(_LINUX_NETDEVICE_H) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) +#define netif_tx_lock_bh(dev) (spin_lock_bh(&(dev)->xmit_lock)) +#define netif_tx_unlock_bh(dev) (spin_unlock_bh(&(dev)->xmit_lock)) #endif + +#if defined(__LINUX_SEQLOCK_H) && !defined(DEFINE_SEQLOCK) +#define DEFINE_SEQLOCK(x) seqlock_t x = SEQLOCK_UNLOCKED +#endif + +#endif diff -r c9720159b983 -r 9559ba7c80f9 unmodified_drivers/linux-2.6/netfront/Kbuild --- a/unmodified_drivers/linux-2.6/netfront/Kbuild Mon Jul 16 14:20:16 2007 -0500 +++ b/unmodified_drivers/linux-2.6/netfront/Kbuild Tue Jul 17 10:20:21 2007 +0100 @@ -2,3 +2,4 @@ include $(M)/overrides.mk obj-m = xen-vnif.o xen-vnif-objs := netfront.o +xen-vnif-objs += accel.o diff -r c9720159b983 -r 9559ba7c80f9 xen/Makefile --- a/xen/Makefile Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/Makefile Tue Jul 17 10:20:21 2007 +0100 @@ -59,7 +59,6 @@ _clean: delete-unfresh-files $(MAKE) -f $(BASEDIR)/Rules.mk -C arch/$(TARGET_ARCH) clean rm -f include/asm *.o $(TARGET)* *~ core rm -f include/asm-*/asm-offsets.h - rm -f include/xen/acm_policy.h .PHONY: _distclean _distclean: clean @@ -72,7 +71,6 @@ _distclean: clean $(TARGET): delete-unfresh-files build-headers $(MAKE) -C tools $(MAKE) -f $(BASEDIR)/Rules.mk include/xen/compile.h - $(MAKE) -f $(BASEDIR)/Rules.mk include/xen/acm_policy.h [ -e include/asm ] || ln -sf asm-$(TARGET_ARCH) include/asm $(MAKE) -f $(BASEDIR)/Rules.mk -C include $(MAKE) -f $(BASEDIR)/Rules.mk -C arch/$(TARGET_ARCH) asm-offsets.s @@ -86,20 +84,6 @@ delete-unfresh-files: @if [ ! -r include/xen/compile.h -o -O include/xen/compile.h ]; then \ rm -f include/xen/compile.h; \ fi - -# acm_policy.h contains security policy for Xen -include/xen/acm_policy.h: - @(set -e; \ - echo "/*"; \ - echo " * DO NOT MODIFY."; \ - echo " *"; \ - echo " * This file was auto-generated by xen/Makefile $<"; \ - echo " *"; \ - echo " */"; \ - echo ""; \ - echo "#ifndef ACM_DEFAULT_SECURITY_POLICY"; \ - echo "#define ACM_DEFAULT_SECURITY_POLICY $(ACM_DEFAULT_SECURITY_POLICY)"; \ - echo "#endif") >$@ # compile.h contains dynamic build info. Rebuilt on every 'make' invocation. include/xen/compile.h: include/xen/compile.h.in diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/Makefile --- a/xen/arch/ia64/Makefile Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/Makefile Tue Jul 17 10:20:21 2007 +0100 @@ -27,7 +27,6 @@ subdir-y += linux-xen > $(BASEDIR)/System.map # Headers do not depend on auto-generated header, but object files do. -HDRS := $(subst $(BASEDIR)/include/asm-ia64/asm-xsi-offsets.h,,$(HDRS)) $(ALL_OBJS): $(BASEDIR)/include/asm-ia64/asm-xsi-offsets.h asm-offsets.s: asm-offsets.c $(BASEDIR)/include/asm-ia64/.offsets.h.stamp @@ -58,6 +57,7 @@ asm-xsi-offsets.s: asm-xsi-offsets.c $(H || ln -sf $(BASEDIR)/include/xen $(BASEDIR)/include/linux [ -e $(BASEDIR)/include/asm-ia64/xen ] \ || ln -sf $(BASEDIR)/include/asm-ia64/linux $(BASEDIR)/include/asm-ia64/xen + touch $@ # I'm sure a Makefile wizard would know a better way to do this xen.lds.s: xen/xen.lds.S $(HDRS) diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/Rules.mk --- a/xen/arch/ia64/Rules.mk Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/Rules.mk Tue Jul 17 10:20:21 2007 +0100 @@ -69,3 +69,5 @@ HDRS += $(wildcard $(BASEDIR)/include/as HDRS += $(wildcard $(BASEDIR)/include/asm-ia64/linux/asm/*.h) HDRS += $(wildcard $(BASEDIR)/include/asm-ia64/linux/byteorder/*.h) HDRS += $(wildcard $(BASEDIR)/include/asm-ia64/hvm/*.h) + +HDRS := $(filter-out %/include/asm-ia64/asm-xsi-offsets.h,$(HDRS)) diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/linux-xen/efi.c --- a/xen/arch/ia64/linux-xen/efi.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/linux-xen/efi.c Tue Jul 17 10:20:21 2007 +0100 @@ -1013,12 +1013,9 @@ efi_memmap_init(unsigned long *s, unsign continue; } #ifdef XEN -// this works around a problem in the ski bootloader -{ - extern long running_on_sim; + /* this works around a problem in the ski bootloader */ if (running_on_sim && md->type != EFI_CONVENTIONAL_MEMORY) continue; -} #endif if (pmd == NULL || !efi_wb(pmd) || efi_md_end(pmd) != md->phys_addr) { contig_low = GRANULEROUNDUP(md->phys_addr); diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/linux-xen/perfmon.c --- a/xen/arch/ia64/linux-xen/perfmon.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/linux-xen/perfmon.c Tue Jul 17 10:20:21 2007 +0100 @@ -7729,7 +7729,7 @@ do_perfmon_op(unsigned long cmd, { unsigned long error = 0; - if (!NONPRIV_OP(cmd) && current->domain != xenoprof_primary_profiler) { + if (!NONPRIV_OP(cmd) && current->domain->domain_id !=0) { gdprintk(XENLOG_INFO, "xen perfmon: " "dom %d denied privileged operation %ld\n", current->domain->domain_id, cmd); diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/linux-xen/sn/kernel/irq.c --- a/xen/arch/ia64/linux-xen/sn/kernel/irq.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/linux-xen/sn/kernel/irq.c Tue Jul 17 10:20:21 2007 +0100 @@ -27,6 +27,7 @@ #include <asm/sn/sn_sal.h> #ifdef XEN +#define pci_dev_get(dev) do {} while(0) #define move_native_irq(foo) do {} while(0) #endif @@ -264,7 +265,6 @@ void sn_irq_init(void) } } -#ifndef XEN static void register_intr_pda(struct sn_irq_info *sn_irq_info) { int irq = sn_irq_info->irq_irq; @@ -278,6 +278,7 @@ static void register_intr_pda(struct sn_ pdacpu(cpu)->sn_first_irq = irq; } +#ifndef XEN static void unregister_intr_pda(struct sn_irq_info *sn_irq_info) { int irq = sn_irq_info->irq_irq; @@ -339,9 +340,7 @@ static void unregister_intr_pda(struct s spin_unlock(&sn_irq_info_lock); #endif } -#endif /* XEN */ - -#ifndef XEN + static void sn_irq_info_free(struct rcu_head *head) { struct sn_irq_info *sn_irq_info; @@ -351,7 +350,6 @@ static void sn_irq_info_free(struct rcu_ } #endif -#ifndef XEN void sn_irq_fixup(struct pci_dev *pci_dev, struct sn_irq_info *sn_irq_info) { nasid_t nasid = sn_irq_info->irq_nasid; @@ -360,7 +358,9 @@ void sn_irq_fixup(struct pci_dev *pci_de pci_dev_get(pci_dev); sn_irq_info->irq_cpuid = cpu; +#ifndef XEN sn_irq_info->irq_pciioinfo = SN_PCIDEV_INFO(pci_dev); +#endif /* link it into the sn_irq[irq] list */ spin_lock(&sn_irq_info_lock); @@ -379,6 +379,7 @@ void sn_irq_fixup(struct pci_dev *pci_de void sn_irq_unfixup(struct pci_dev *pci_dev) { +#ifndef XEN struct sn_irq_info *sn_irq_info; /* Only cleanup IRQ stuff if this device has a host bus context */ @@ -408,8 +409,8 @@ void sn_irq_unfixup(struct pci_dev *pci_ #endif pci_dev_put(pci_dev); -} -#endif +#endif +} static inline void sn_call_force_intr_provider(struct sn_irq_info *sn_irq_info) diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c --- a/xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c Tue Jul 17 10:20:21 2007 +0100 @@ -160,21 +160,97 @@ void sn_tlb_migrate_finish(struct mm_str // static cpumask_t mask_all = CPU_MASK_ALL; #endif +#ifdef XEN +static DEFINE_SPINLOCK(sn2_ptcg_lock); + +struct sn_flush_struct { + unsigned long start; + unsigned long end; + unsigned long nbits; +}; + +static void sn_flush_ptcga_cpu(void *ptr) +{ + struct sn_flush_struct *sn_flush = ptr; + unsigned long start, end, nbits; + + start = sn_flush->start; + end = sn_flush->end; + nbits = sn_flush->nbits; + + /* + * Contention me harder!!! + */ + /* HW requires global serialization of ptc.ga. */ + spin_lock(&sn2_ptcg_lock); + { + do { + /* + * Flush ALAT entries also. + */ + ia64_ptcga(start, (nbits<<2)); + ia64_srlz_i(); + start += (1UL << nbits); + } while (start < end); + } + spin_unlock(&sn2_ptcg_lock); +} + void -#ifndef XEN +sn2_global_tlb_purge(unsigned long start, + unsigned long end, unsigned long nbits) +{ + nodemask_t nodes_flushed; + cpumask_t selected_cpus; + int cpu, cnode, i; + static DEFINE_SPINLOCK(sn2_ptcg_lock2); + + nodes_clear(nodes_flushed); + cpus_clear(selected_cpus); + + spin_lock(&sn2_ptcg_lock2); + node_set(cpu_to_node(smp_processor_id()), nodes_flushed); + i = 0; + for_each_cpu(cpu) { + cnode = cpu_to_node(cpu); + if (!node_isset(cnode, nodes_flushed)) { + cpu_set(cpu, selected_cpus); + i++; + } + node_set(cnode, nodes_flushed); + } + + /* HW requires global serialization of ptc.ga. */ + spin_lock(&sn2_ptcg_lock); + { + do { + /* + * Flush ALAT entries also. + */ + ia64_ptcga(start, (nbits<<2)); + ia64_srlz_i(); + start += (1UL << nbits); + } while (start < end); + } + spin_unlock(&sn2_ptcg_lock); + + if (i) { + struct sn_flush_struct flush_data; + flush_data.start = start; + flush_data.end = end; + flush_data.nbits = nbits; + on_selected_cpus(selected_cpus, sn_flush_ptcga_cpu, + &flush_data, 1, 1); + } + spin_unlock(&sn2_ptcg_lock2); +} +#else +void sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, -#else -sn2_global_tlb_purge(unsigned long start, -#endif unsigned long end, unsigned long nbits) { int i, ibegin, shub1, cnode, mynasid, cpu, lcpu = 0, nasid; -#ifndef XEN int mymm = (mm == current->active_mm && mm == current->mm); -#else - // struct mm_struct *mm; - int mymm = 0; -#endif int use_cpu_ptcga; volatile unsigned long *ptc0, *ptc1; unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value, old_rr = 0; @@ -206,6 +282,7 @@ sn2_global_tlb_purge(unsigned long start preempt_disable(); +#ifndef XEN if (likely(i == 1 && lcpu == smp_processor_id() && mymm)) { do { ia64_ptcl(start, nbits << 2); @@ -217,13 +294,8 @@ sn2_global_tlb_purge(unsigned long start return; } -#ifndef XEN if (atomic_read(&mm->mm_users) == 1 && mymm) { -#ifndef XEN /* I hate Xen! */ flush_tlb_mm(mm); -#else - flush_tlb_mask(mask_all); -#endif __get_cpu_var(ptcstats).change_rid++; preempt_enable(); return; @@ -335,6 +407,7 @@ sn2_global_tlb_purge(unsigned long start preempt_enable(); } +#endif /* * sn2_ptc_deadlock_recovery diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/vmx/Makefile --- a/xen/arch/ia64/vmx/Makefile Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/vmx/Makefile Tue Jul 17 10:20:21 2007 +0100 @@ -10,7 +10,7 @@ obj-y += vmx_interrupt.o obj-y += vmx_interrupt.o obj-y += vmx_ivt.o obj-y += vmx_phy_mode.o -obj-y += vmx_process.o +obj-y += vmx_fault.o obj-y += vmx_support.o obj-y += vmx_utility.o obj-y += vmx_vcpu.o diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/vmx/mmio.c --- a/xen/arch/ia64/vmx/mmio.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/vmx/mmio.c Tue Jul 17 10:20:21 2007 +0100 @@ -200,6 +200,21 @@ static inline void set_os_type(VCPU *v, if (type > OS_BASE && type < OS_END) { v->domain->arch.vmx_platform.gos_type = type; gdprintk(XENLOG_INFO, "Guest OS : %s\n", guest_os_name[type - OS_BASE]); + + if (GOS_WINDOWS(v)) { + struct xen_ia64_opt_feature optf; + + /* Windows identity maps regions 4 & 5 */ + optf.cmd = XEN_IA64_OPTF_IDENT_MAP_REG4; + optf.on = XEN_IA64_OPTF_ON; + optf.pgprot = (_PAGE_P|_PAGE_A|_PAGE_D|_PAGE_MA_WB|_PAGE_AR_RW); + optf.key = 0; + domain_opt_feature(&optf); + + optf.cmd = XEN_IA64_OPTF_IDENT_MAP_REG5; + optf.pgprot = (_PAGE_P|_PAGE_A|_PAGE_D|_PAGE_MA_UC|_PAGE_AR_RW); + domain_opt_feature(&optf); + } } } diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/vmx/vmmu.c --- a/xen/arch/ia64/vmx/vmmu.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/vmx/vmmu.c Tue Jul 17 10:20:21 2007 +0100 @@ -540,8 +540,7 @@ IA64FAULT vmx_vcpu_ptc_e(VCPU *vcpu, u64 IA64FAULT vmx_vcpu_ptc_g(VCPU *vcpu, u64 va, u64 ps) { - vmx_vcpu_ptc_ga(vcpu, va, ps); - return IA64_ILLOP_FAULT; + return vmx_vcpu_ptc_ga(vcpu, va, ps); } /* IA64FAULT vmx_vcpu_ptc_ga(VCPU *vcpu, u64 va, u64 ps) diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/vmx/vmx_fault.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/arch/ia64/vmx/vmx_fault.c Tue Jul 17 10:20:21 2007 +0100 @@ -0,0 +1,524 @@ +/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ +/* + * vmx_fault.c: handling VMX architecture-related VM exits + * Copyright (c) 2005, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * 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. + * + * Xiaoyan Feng (Fleming Feng) <fleming.feng@xxxxxxxxx> + * Xuefei Xu (Anthony Xu) (Anthony.xu@xxxxxxxxx) + */ + +#include <xen/config.h> +#include <xen/lib.h> +#include <xen/errno.h> +#include <xen/sched.h> +#include <xen/smp.h> +#include <asm/ptrace.h> +#include <xen/delay.h> + +#include <linux/efi.h> /* FOR EFI_UNIMPLEMENTED */ +#include <asm/sal.h> /* FOR struct ia64_sal_retval */ + +#include <asm/system.h> +#include <asm/io.h> +#include <asm/processor.h> +#include <asm/desc.h> +#include <asm/vlsapic.h> +#include <xen/irq.h> +#include <xen/event.h> +#include <asm/regionreg.h> +#include <asm/privop.h> +#include <asm/ia64_int.h> +#include <asm/debugger.h> +//#include <asm/hpsim_ssc.h> +#include <asm/dom_fw.h> +#include <asm/vmx_vcpu.h> +#include <asm/kregs.h> +#include <asm/vmx.h> +#include <asm/vmmu.h> +#include <asm/vmx_mm_def.h> +#include <asm/vmx_phy_mode.h> +#include <xen/mm.h> +#include <asm/vmx_pal.h> +/* reset all PSR field to 0, except up,mfl,mfh,pk,dt,rt,mc,it */ +#define INITIAL_PSR_VALUE_AT_INTERRUPTION 0x0000001808028034 + + +extern void die_if_kernel(char *str, struct pt_regs *regs, long err); +extern void rnat_consumption (VCPU *vcpu); +extern void alt_itlb (VCPU *vcpu, u64 vadr); +extern void itlb_fault (VCPU *vcpu, u64 vadr); +extern void ivhpt_fault (VCPU *vcpu, u64 vadr); +extern unsigned long handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr); + +#define DOMN_PAL_REQUEST 0x110000 +#define DOMN_SAL_REQUEST 0x110001 + +static u64 vec2off[68] = {0x0,0x400,0x800,0xc00,0x1000,0x1400,0x1800, + 0x1c00,0x2000,0x2400,0x2800,0x2c00,0x3000,0x3400,0x3800,0x3c00,0x4000, + 0x4400,0x4800,0x4c00,0x5000,0x5100,0x5200,0x5300,0x5400,0x5500,0x5600, + 0x5700,0x5800,0x5900,0x5a00,0x5b00,0x5c00,0x5d00,0x5e00,0x5f00,0x6000, + 0x6100,0x6200,0x6300,0x6400,0x6500,0x6600,0x6700,0x6800,0x6900,0x6a00, + 0x6b00,0x6c00,0x6d00,0x6e00,0x6f00,0x7000,0x7100,0x7200,0x7300,0x7400, + 0x7500,0x7600,0x7700,0x7800,0x7900,0x7a00,0x7b00,0x7c00,0x7d00,0x7e00, + 0x7f00 +}; + + + +void vmx_reflect_interruption(u64 ifa, u64 isr, u64 iim, + u64 vec, REGS *regs) +{ + u64 status, vector; + VCPU *vcpu = current; + u64 vpsr = VCPU(vcpu, vpsr); + + vector = vec2off[vec]; + + switch (vec) { + case 5: // IA64_DATA_NESTED_TLB_VECTOR + break; + case 22: // IA64_INST_ACCESS_RIGHTS_VECTOR + if (!(vpsr & IA64_PSR_IC)) + goto nested_fault; + if (vhpt_access_rights_fixup(vcpu, ifa, 0)) + return; + break; + + case 25: // IA64_DISABLED_FPREG_VECTOR + if (!(vpsr & IA64_PSR_IC)) + goto nested_fault; + if (FP_PSR(vcpu) & IA64_PSR_DFH) { + FP_PSR(vcpu) = IA64_PSR_MFH; + if (__ia64_per_cpu_var(fp_owner) != vcpu) + __ia64_load_fpu(vcpu->arch._thread.fph); + } + if (!(VCPU(vcpu, vpsr) & IA64_PSR_DFH)) { + regs->cr_ipsr &= ~IA64_PSR_DFH; + return; + } + + break; + + case 32: // IA64_FP_FAULT_VECTOR + if (!(vpsr & IA64_PSR_IC)) + goto nested_fault; + // handle fpswa emulation + // fp fault + status = handle_fpu_swa(1, regs, isr); + if (!status) { + vcpu_increment_iip(vcpu); + return; + } else if (IA64_RETRY == status) + return; + break; + + case 33: // IA64_FP_TRAP_VECTOR + if (!(vpsr & IA64_PSR_IC)) + goto nested_fault; + //fp trap + status = handle_fpu_swa(0, regs, isr); + if (!status) + return; + else if (IA64_RETRY == status) { + vcpu_decrement_iip(vcpu); + return; + } + break; + + case 29: // IA64_DEBUG_VECTOR + case 35: // IA64_TAKEN_BRANCH_TRAP_VECTOR + case 36: // IA64_SINGLE_STEP_TRAP_VECTOR + if (vmx_guest_kernel_mode(regs) + && current->domain->debugger_attached) { + domain_pause_for_debugger(); + return; + } + if (!(vpsr & IA64_PSR_IC)) + goto nested_fault; + break; + + default: + if (!(vpsr & IA64_PSR_IC)) + goto nested_fault; + break; + } + VCPU(vcpu,isr)=isr; + VCPU(vcpu,iipa) = regs->cr_iip; + if (vector == IA64_BREAK_VECTOR || vector == IA64_SPECULATION_VECTOR) + VCPU(vcpu,iim) = iim; + else { + set_ifa_itir_iha(vcpu,ifa,1,1,1); + } + inject_guest_interruption(vcpu, vector); + return; + + nested_fault: + panic_domain(regs, "Guest nested fault vector=%lx!\n", vector); +} + + +IA64FAULT +vmx_ia64_handle_break (unsigned long ifa, struct pt_regs *regs, unsigned long isr, unsigned long iim) +{ + struct domain *d = current->domain; + struct vcpu *v = current; + + perfc_incr(vmx_ia64_handle_break); +#ifdef CRASH_DEBUG + if ((iim == 0 || iim == CDB_BREAK_NUM) && !guest_mode(regs) && + IS_VMM_ADDRESS(regs->cr_iip)) { + if (iim == 0) + show_registers(regs); + debugger_trap_fatal(0 /* don't care */, regs); + } else +#endif + { + if (iim == 0) + vmx_die_if_kernel("Break 0 in Hypervisor.", regs, iim); + + if (ia64_psr(regs)->cpl == 0) { + /* Allow hypercalls only when cpl = 0. */ + if (iim == d->arch.breakimm) { + ia64_hypercall(regs); + vcpu_increment_iip(v); + return IA64_NO_FAULT; + } + else if(iim == DOMN_PAL_REQUEST){ + pal_emul(v); + vcpu_increment_iip(v); + return IA64_NO_FAULT; + }else if(iim == DOMN_SAL_REQUEST){ + sal_emul(v); + vcpu_increment_iip(v); + return IA64_NO_FAULT; + } + } + vmx_reflect_interruption(ifa,isr,iim,11,regs); + } + return IA64_NO_FAULT; +} + + +void save_banked_regs_to_vpd(VCPU *v, REGS *regs) +{ + unsigned long i=0UL, * src,* dst, *sunat, *dunat; + IA64_PSR vpsr; + src=®s->r16; + sunat=®s->eml_unat; + vpsr.val = VCPU(v, vpsr); + if(vpsr.bn){ + dst = &VCPU(v, vgr[0]); + dunat =&VCPU(v, vnat); + __asm__ __volatile__ (";;extr.u %0 = %1,%4,16;; \ + dep %2 = %0, %2, 0, 16;; \ + st8 [%3] = %2;;" + ::"r"(i),"r"(*sunat),"r"(*dunat),"r"(dunat),"i"(IA64_PT_REGS_R16_SLOT):"memory"); + + }else{ + dst = &VCPU(v, vbgr[0]); +// dunat =&VCPU(v, vbnat); +// __asm__ __volatile__ (";;extr.u %0 = %1,%4,16;; +// dep %2 = %0, %2, 16, 16;; +// st8 [%3] = %2;;" +// ::"r"(i),"r"(*sunat),"r"(*dunat),"r"(dunat),"i"(IA64_PT_REGS_R16_SLOT):"memory"); + + } + for(i=0; i<16; i++) + *dst++ = *src++; +} + + +// ONLY gets called from ia64_leave_kernel +// ONLY call with interrupts disabled?? (else might miss one?) +// NEVER successful if already reflecting a trap/fault because psr.i==0 +void leave_hypervisor_tail(void) +{ + struct domain *d = current->domain; + struct vcpu *v = current; + + // FIXME: Will this work properly if doing an RFI??? + if (!is_idle_domain(d) ) { // always comes from guest +// struct pt_regs *user_regs = vcpu_regs(current); + local_irq_enable(); + do_softirq(); + local_irq_disable(); + + if (v->vcpu_id == 0) { + unsigned long callback_irq = + d->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ]; + + if ( v->arch.arch_vmx.pal_init_pending ) { + /*inject INIT interruption to guest pal*/ + v->arch.arch_vmx.pal_init_pending = 0; + deliver_pal_init(v); + return; + } + + /* + * val[63:56] == 1: val[55:0] is a delivery PCI INTx line: + * Domain = val[47:32], Bus = val[31:16], + * DevFn = val[15: 8], IntX = val[ 1: 0] + * val[63:56] == 0: val[55:0] is a delivery as GSI + */ + if (callback_irq != 0 && local_events_need_delivery()) { + /* change level for para-device callback irq */ + /* use level irq to send discrete event */ + if ((uint8_t)(callback_irq >> 56) == 1) { + /* case of using PCI INTx line as callback irq */ + int pdev = (callback_irq >> 11) & 0x1f; + int pintx = callback_irq & 3; + viosapic_set_pci_irq(d, pdev, pintx, 1); + viosapic_set_pci_irq(d, pdev, pintx, 0); + } else { + /* case of using GSI as callback irq */ + viosapic_set_irq(d, callback_irq, 1); + viosapic_set_irq(d, callback_irq, 0); + } + } + } + + rmb(); + if (xchg(&v->arch.irq_new_pending, 0)) { + v->arch.irq_new_condition = 0; + vmx_check_pending_irq(v); + return; + } + + if (v->arch.irq_new_condition) { + v->arch.irq_new_condition = 0; + vhpi_detection(v); + } + } +} + +extern ia64_rr vmx_vcpu_rr(VCPU *vcpu, u64 vadr); + +static int vmx_handle_lds(REGS* regs) +{ + regs->cr_ipsr |=IA64_PSR_ED; + return IA64_FAULT; +} + +/* We came here because the H/W VHPT walker failed to find an entry */ +IA64FAULT +vmx_hpw_miss(u64 vadr, u64 vec, REGS* regs) +{ + IA64_PSR vpsr; + int type; + u64 vhpt_adr, gppa, pteval, rr, itir; + ISR misr; + PTA vpta; + thash_data_t *data; + VCPU *v = current; + + vpsr.val = VCPU(v, vpsr); + misr.val = VMX(v,cr_isr); + + if (vec == 1) + type = ISIDE_TLB; + else if (vec == 2) + type = DSIDE_TLB; + else + panic_domain(regs, "wrong vec:%lx\n", vec); + + /* Physical mode and region is 0 or 4. */ + if (is_physical_mode(v) && (!((vadr<<1)>>62))) { + if (vec == 2) { + /* DTLB miss. */ + if (misr.sp) /* Refer to SDM Vol2 Table 4-11,4-12 */ + return vmx_handle_lds(regs); + if (v->domain != dom0 + && __gpfn_is_io(v->domain, (vadr << 1) >> (PAGE_SHIFT + 1))) { + emulate_io_inst(v, ((vadr<<1)>>1),4); // UC + return IA64_FAULT; + } + } + physical_tlb_miss(v, vadr, type); + return IA64_FAULT; + } + +try_again: + if ((data=vtlb_lookup(v, vadr,type)) != 0) { + if (v->domain != dom0 && type == DSIDE_TLB) { + if (misr.sp) { /* Refer to SDM Vol2 Table 4-10,4-12 */ + if ((data->ma == VA_MATTR_UC) || (data->ma == VA_MATTR_UCE)) + return vmx_handle_lds(regs); + } + gppa = (vadr & ((1UL << data->ps) - 1)) + + (data->ppn >> (data->ps - 12) << data->ps); + if (__gpfn_is_io(v->domain, gppa >> PAGE_SHIFT)) { + if (misr.sp) + panic_domain(NULL, "ld.s on I/O page not with UC attr." + " pte=0x%lx\n", data->page_flags); + if (data->pl >= ((regs->cr_ipsr >> IA64_PSR_CPL0_BIT) & 3)) + emulate_io_inst(v, gppa, data->ma); + else { + vcpu_set_isr(v, misr.val); + data_access_rights(v, vadr); + } + return IA64_FAULT; + } + } + thash_vhpt_insert(v, data->page_flags, data->itir, vadr, type); + + } else if (type == DSIDE_TLB) { + struct opt_feature* optf = &(v->domain->arch.opt_feature); + + if (misr.sp) + return vmx_handle_lds(regs); + + vcpu_get_rr(v, vadr, &rr); + itir = rr & (RR_RID_MASK | RR_PS_MASK); + + if (!vhpt_enabled(v, vadr, misr.rs ? RSE_REF : DATA_REF)) { + /* windows use region 4 and 5 for identity mapping */ + if (optf->mask & XEN_IA64_OPTF_IDENT_MAP_REG4 && + REGION_NUMBER(vadr) == 4 && !(regs->cr_ipsr & IA64_PSR_CPL) && + REGION_OFFSET(vadr) <= _PAGE_PPN_MASK) { + + pteval = PAGEALIGN(REGION_OFFSET(vadr), itir_ps(itir)) | + optf->im_reg4.pgprot; + if (thash_purge_and_insert(v, pteval, itir, vadr, type)) + goto try_again; + return IA64_NO_FAULT; + } + if (optf->mask & XEN_IA64_OPTF_IDENT_MAP_REG5 && + REGION_NUMBER(vadr) == 5 && !(regs->cr_ipsr & IA64_PSR_CPL) && + REGION_OFFSET(vadr) <= _PAGE_PPN_MASK) { + + pteval = PAGEALIGN(REGION_OFFSET(vadr), itir_ps(itir)) | + optf->im_reg5.pgprot; + if (thash_purge_and_insert(v, pteval, itir, vadr, type)) + goto try_again; + return IA64_NO_FAULT; + } + if (vpsr.ic) { + vcpu_set_isr(v, misr.val); + alt_dtlb(v, vadr); + return IA64_FAULT; + } else { + nested_dtlb(v); + return IA64_FAULT; + } + } + + vpta.val = vmx_vcpu_get_pta(v); + if (vpta.vf) { + /* Long format is not yet supported. */ + if (vpsr.ic) { + vcpu_set_isr(v, misr.val); + dtlb_fault(v, vadr); + return IA64_FAULT; + } else { + nested_dtlb(v); + return IA64_FAULT; + } + } + + /* avoid recursively walking (short format) VHPT */ + if (!(optf->mask & XEN_IA64_OPTF_IDENT_MAP_REG4) && + !(optf->mask & XEN_IA64_OPTF_IDENT_MAP_REG5) && + (((vadr ^ vpta.val) << 3) >> (vpta.size + 3)) == 0) { + + if (vpsr.ic) { + vcpu_set_isr(v, misr.val); + dtlb_fault(v, vadr); + return IA64_FAULT; + } else { + nested_dtlb(v); + return IA64_FAULT; + } + } + + vhpt_adr = vmx_vcpu_thash(v, vadr); + if (!guest_vhpt_lookup(vhpt_adr, &pteval)) { + /* VHPT successfully read. */ + if (!(pteval & _PAGE_P)) { + if (vpsr.ic) { + vcpu_set_isr(v, misr.val); + dtlb_fault(v, vadr); + return IA64_FAULT; + } else { + nested_dtlb(v); + return IA64_FAULT; + } + } else if ((pteval & _PAGE_MA_MASK) != _PAGE_MA_ST) { + thash_purge_and_insert(v, pteval, itir, vadr, DSIDE_TLB); + return IA64_NO_FAULT; + } else if (vpsr.ic) { + vcpu_set_isr(v, misr.val); + dtlb_fault(v, vadr); + return IA64_FAULT; + } else { + nested_dtlb(v); + return IA64_FAULT; + } + } else { + /* Can't read VHPT. */ + if (vpsr.ic) { + vcpu_set_isr(v, misr.val); + dvhpt_fault(v, vadr); + return IA64_FAULT; + } else { + nested_dtlb(v); + return IA64_FAULT; + } + } + } else if (type == ISIDE_TLB) { + + if (!vpsr.ic) + misr.ni = 1; + if (!vhpt_enabled(v, vadr, INST_REF)) { + vcpu_set_isr(v, misr.val); + alt_itlb(v, vadr); + return IA64_FAULT; + } + + vpta.val = vmx_vcpu_get_pta(v); + if (vpta.vf) { + /* Long format is not yet supported. */ + vcpu_set_isr(v, misr.val); + itlb_fault(v, vadr); + return IA64_FAULT; + } + + + vhpt_adr = vmx_vcpu_thash(v, vadr); + if (!guest_vhpt_lookup(vhpt_adr, &pteval)) { + /* VHPT successfully read. */ + if (pteval & _PAGE_P) { + if ((pteval & _PAGE_MA_MASK) == _PAGE_MA_ST) { + vcpu_set_isr(v, misr.val); + itlb_fault(v, vadr); + return IA64_FAULT; + } + vcpu_get_rr(v, vadr, &rr); + itir = rr & (RR_RID_MASK | RR_PS_MASK); + thash_purge_and_insert(v, pteval, itir, vadr, ISIDE_TLB); + return IA64_NO_FAULT; + } else { + vcpu_set_isr(v, misr.val); + inst_page_not_present(v, vadr); + return IA64_FAULT; + } + } else { + vcpu_set_isr(v, misr.val); + ivhpt_fault(v, vadr); + return IA64_FAULT; + } + } + return IA64_NO_FAULT; +} diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/vmx/vmx_init.c --- a/xen/arch/ia64/vmx/vmx_init.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/vmx/vmx_init.c Tue Jul 17 10:20:21 2007 +0100 @@ -283,9 +283,13 @@ static void vmx_create_event_channels(st } } +/* + * Event channel has destoryed in domain_kill(), so we needn't + * do anything here + */ static void vmx_release_assist_channel(struct vcpu *v) { - free_xen_event_channel(v, v->arch.arch_vmx.xen_port); + return; } /* diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/vmx/vmx_ivt.S --- a/xen/arch/ia64/vmx/vmx_ivt.S Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/vmx/vmx_ivt.S Tue Jul 17 10:20:21 2007 +0100 @@ -1001,7 +1001,7 @@ END(vmx_speculation_vector) // 0x5900 Entry 29 (size 16 bundles) Debug (16,28,56) ENTRY(vmx_debug_vector) VMX_DBG_FAULT(29) - VMX_FAULT(29) + VMX_REFLECT(29) END(vmx_debug_vector) .org vmx_ia64_ivt+0x5a00 diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/vmx/vmx_minstate.h --- a/xen/arch/ia64/vmx/vmx_minstate.h Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/vmx/vmx_minstate.h Tue Jul 17 10:20:21 2007 +0100 @@ -124,9 +124,9 @@ ;; \ tbit.z p6,p0=r29,IA64_PSR_VM_BIT; \ ;; \ - tbit.nz.or p6,p0 = r18,39; \ + tbit.nz.or p6,p0 = r18,IA64_ISR_NI_BIT; \ ;; \ -(p6) br.sptk.few vmx_panic; \ +(p6) br.spnt.few vmx_panic; \ tbit.z p0,p15=r29,IA64_PSR_I_BIT; \ mov r1=r16; \ /* mov r21=r16; */ \ diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/vmx/vmx_process.c --- a/xen/arch/ia64/vmx/vmx_process.c Mon Jul 16 14:20:16 2007 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,503 +0,0 @@ -/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ -/* - * vmx_process.c: handling VMX architecture-related VM exits - * Copyright (c) 2005, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * 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. - * - * Xiaoyan Feng (Fleming Feng) <fleming.feng@xxxxxxxxx> - * Xuefei Xu (Anthony Xu) (Anthony.xu@xxxxxxxxx) - */ - -#include <xen/config.h> -#include <xen/lib.h> -#include <xen/errno.h> -#include <xen/sched.h> -#include <xen/smp.h> -#include <asm/ptrace.h> -#include <xen/delay.h> - -#include <linux/efi.h> /* FOR EFI_UNIMPLEMENTED */ -#include <asm/sal.h> /* FOR struct ia64_sal_retval */ - -#include <asm/system.h> -#include <asm/io.h> -#include <asm/processor.h> -#include <asm/desc.h> -#include <asm/vlsapic.h> -#include <xen/irq.h> -#include <xen/event.h> -#include <asm/regionreg.h> -#include <asm/privop.h> -#include <asm/ia64_int.h> -#include <asm/debugger.h> -//#include <asm/hpsim_ssc.h> -#include <asm/dom_fw.h> -#include <asm/vmx_vcpu.h> -#include <asm/kregs.h> -#include <asm/vmx.h> -#include <asm/vmmu.h> -#include <asm/vmx_mm_def.h> -#include <asm/vmx_phy_mode.h> -#include <xen/mm.h> -#include <asm/vmx_pal.h> -/* reset all PSR field to 0, except up,mfl,mfh,pk,dt,rt,mc,it */ -#define INITIAL_PSR_VALUE_AT_INTERRUPTION 0x0000001808028034 - - -extern void die_if_kernel(char *str, struct pt_regs *regs, long err); -extern void rnat_consumption (VCPU *vcpu); -extern void alt_itlb (VCPU *vcpu, u64 vadr); -extern void itlb_fault (VCPU *vcpu, u64 vadr); -extern void ivhpt_fault (VCPU *vcpu, u64 vadr); -extern unsigned long handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr); - -#define DOMN_PAL_REQUEST 0x110000 -#define DOMN_SAL_REQUEST 0x110001 - -static u64 vec2off[68] = {0x0,0x400,0x800,0xc00,0x1000,0x1400,0x1800, - 0x1c00,0x2000,0x2400,0x2800,0x2c00,0x3000,0x3400,0x3800,0x3c00,0x4000, - 0x4400,0x4800,0x4c00,0x5000,0x5100,0x5200,0x5300,0x5400,0x5500,0x5600, - 0x5700,0x5800,0x5900,0x5a00,0x5b00,0x5c00,0x5d00,0x5e00,0x5f00,0x6000, - 0x6100,0x6200,0x6300,0x6400,0x6500,0x6600,0x6700,0x6800,0x6900,0x6a00, - 0x6b00,0x6c00,0x6d00,0x6e00,0x6f00,0x7000,0x7100,0x7200,0x7300,0x7400, - 0x7500,0x7600,0x7700,0x7800,0x7900,0x7a00,0x7b00,0x7c00,0x7d00,0x7e00, - 0x7f00 -}; - - - -void vmx_reflect_interruption(u64 ifa, u64 isr, u64 iim, - u64 vec, REGS *regs) -{ - u64 status, vector; - VCPU *vcpu = current; - u64 vpsr = VCPU(vcpu, vpsr); - - vector = vec2off[vec]; - if(!(vpsr&IA64_PSR_IC)&&(vector!=IA64_DATA_NESTED_TLB_VECTOR)){ - panic_domain(regs, "Guest nested fault vector=%lx!\n", vector); - } - - switch (vec) { - - case 22: // IA64_INST_ACCESS_RIGHTS_VECTOR - if (vhpt_access_rights_fixup(vcpu, ifa, 0)) - return; - break; - - case 25: // IA64_DISABLED_FPREG_VECTOR - - if (FP_PSR(vcpu) & IA64_PSR_DFH) { - FP_PSR(vcpu) = IA64_PSR_MFH; - if (__ia64_per_cpu_var(fp_owner) != vcpu) - __ia64_load_fpu(vcpu->arch._thread.fph); - } - if (!(VCPU(vcpu, vpsr) & IA64_PSR_DFH)) { - regs->cr_ipsr &= ~IA64_PSR_DFH; - return; - } - - break; - - case 32: // IA64_FP_FAULT_VECTOR - // handle fpswa emulation - // fp fault - status = handle_fpu_swa(1, regs, isr); - if (!status) { - vcpu_increment_iip(vcpu); - return; - } else if (IA64_RETRY == status) - return; - break; - - case 33: // IA64_FP_TRAP_VECTOR - //fp trap - status = handle_fpu_swa(0, regs, isr); - if (!status) - return; - else if (IA64_RETRY == status) { - vcpu_decrement_iip(vcpu); - return; - } - break; - - } - VCPU(vcpu,isr)=isr; - VCPU(vcpu,iipa) = regs->cr_iip; - if (vector == IA64_BREAK_VECTOR || vector == IA64_SPECULATION_VECTOR) - VCPU(vcpu,iim) = iim; - else { - set_ifa_itir_iha(vcpu,ifa,1,1,1); - } - inject_guest_interruption(vcpu, vector); -} - - -IA64FAULT -vmx_ia64_handle_break (unsigned long ifa, struct pt_regs *regs, unsigned long isr, unsigned long iim) -{ - struct domain *d = current->domain; - struct vcpu *v = current; - - perfc_incr(vmx_ia64_handle_break); -#ifdef CRASH_DEBUG - if ((iim == 0 || iim == CDB_BREAK_NUM) && !guest_mode(regs) && - IS_VMM_ADDRESS(regs->cr_iip)) { - if (iim == 0) - show_registers(regs); - debugger_trap_fatal(0 /* don't care */, regs); - } else -#endif - { - if (iim == 0) - vmx_die_if_kernel("Break 0 in Hypervisor.", regs, iim); - - if (ia64_psr(regs)->cpl == 0) { - /* Allow hypercalls only when cpl = 0. */ - if (iim == d->arch.breakimm) { - ia64_hypercall(regs); - vcpu_increment_iip(v); - return IA64_NO_FAULT; - } - else if(iim == DOMN_PAL_REQUEST){ - pal_emul(v); - vcpu_increment_iip(v); - return IA64_NO_FAULT; - }else if(iim == DOMN_SAL_REQUEST){ - sal_emul(v); - vcpu_increment_iip(v); - return IA64_NO_FAULT; - } - } - vmx_reflect_interruption(ifa,isr,iim,11,regs); - } - return IA64_NO_FAULT; -} - - -void save_banked_regs_to_vpd(VCPU *v, REGS *regs) -{ - unsigned long i=0UL, * src,* dst, *sunat, *dunat; - IA64_PSR vpsr; - src=®s->r16; - sunat=®s->eml_unat; - vpsr.val = VCPU(v, vpsr); - if(vpsr.bn){ - dst = &VCPU(v, vgr[0]); - dunat =&VCPU(v, vnat); - __asm__ __volatile__ (";;extr.u %0 = %1,%4,16;; \ - dep %2 = %0, %2, 0, 16;; \ - st8 [%3] = %2;;" - ::"r"(i),"r"(*sunat),"r"(*dunat),"r"(dunat),"i"(IA64_PT_REGS_R16_SLOT):"memory"); - - }else{ - dst = &VCPU(v, vbgr[0]); -// dunat =&VCPU(v, vbnat); -// __asm__ __volatile__ (";;extr.u %0 = %1,%4,16;; -// dep %2 = %0, %2, 16, 16;; -// st8 [%3] = %2;;" -// ::"r"(i),"r"(*sunat),"r"(*dunat),"r"(dunat),"i"(IA64_PT_REGS_R16_SLOT):"memory"); - - } - for(i=0; i<16; i++) - *dst++ = *src++; -} - - -// ONLY gets called from ia64_leave_kernel -// ONLY call with interrupts disabled?? (else might miss one?) -// NEVER successful if already reflecting a trap/fault because psr.i==0 -void leave_hypervisor_tail(void) -{ - struct domain *d = current->domain; - struct vcpu *v = current; - - // FIXME: Will this work properly if doing an RFI??? - if (!is_idle_domain(d) ) { // always comes from guest -// struct pt_regs *user_regs = vcpu_regs(current); - local_irq_enable(); - do_softirq(); - local_irq_disable(); - - if (v->vcpu_id == 0) { - unsigned long callback_irq = - d->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ]; - - if ( v->arch.arch_vmx.pal_init_pending ) { - /*inject INIT interruption to guest pal*/ - v->arch.arch_vmx.pal_init_pending = 0; - deliver_pal_init(v); - return; - } - - /* - * val[63:56] == 1: val[55:0] is a delivery PCI INTx line: - * Domain = val[47:32], Bus = val[31:16], - * DevFn = val[15: 8], IntX = val[ 1: 0] - * val[63:56] == 0: val[55:0] is a delivery as GSI - */ - if (callback_irq != 0 && local_events_need_delivery()) { - /* change level for para-device callback irq */ - /* use level irq to send discrete event */ - if ((uint8_t)(callback_irq >> 56) == 1) { - /* case of using PCI INTx line as callback irq */ - int pdev = (callback_irq >> 11) & 0x1f; - int pintx = callback_irq & 3; - viosapic_set_pci_irq(d, pdev, pintx, 1); - viosapic_set_pci_irq(d, pdev, pintx, 0); - } else { - /* case of using GSI as callback irq */ - viosapic_set_irq(d, callback_irq, 1); - viosapic_set_irq(d, callback_irq, 0); - } - } - } - - rmb(); - if (xchg(&v->arch.irq_new_pending, 0)) { - v->arch.irq_new_condition = 0; - vmx_check_pending_irq(v); - return; - } - - if (v->arch.irq_new_condition) { - v->arch.irq_new_condition = 0; - vhpi_detection(v); - } - } -} - -extern ia64_rr vmx_vcpu_rr(VCPU *vcpu, u64 vadr); - -static int vmx_handle_lds(REGS* regs) -{ - regs->cr_ipsr |=IA64_PSR_ED; - return IA64_FAULT; -} - -/* We came here because the H/W VHPT walker failed to find an entry */ -IA64FAULT -vmx_hpw_miss(u64 vadr , u64 vec, REGS* regs) -{ - IA64_PSR vpsr; - int type; - u64 vhpt_adr, gppa, pteval, rr, itir; - ISR misr; - PTA vpta; - thash_data_t *data; - VCPU *v = current; - - vpsr.val = VCPU(v, vpsr); - misr.val = VMX(v,cr_isr); - - if (vec == 1) - type = ISIDE_TLB; - else if (vec == 2) - type = DSIDE_TLB; - else - panic_domain(regs, "wrong vec:%lx\n", vec); - - if(is_physical_mode(v)&&(!(vadr<<1>>62))){ - if(vec==2){ - if (misr.sp) /* Refer to SDM Vol2 Table 4-11,4-12 */ - return vmx_handle_lds(regs); - if (v->domain != dom0 - && __gpfn_is_io(v->domain, (vadr << 1) >> (PAGE_SHIFT + 1))) { - emulate_io_inst(v,((vadr<<1)>>1),4); // UC - return IA64_FAULT; - } - } - physical_tlb_miss(v, vadr, type); - return IA64_FAULT; - } - -try_again: - if((data=vtlb_lookup(v, vadr,type))!=0){ - if (v->domain != dom0 && type == DSIDE_TLB) { - if (misr.sp) { /* Refer to SDM Vol2 Table 4-10,4-12 */ - if ((data->ma == VA_MATTR_UC) || (data->ma == VA_MATTR_UCE)) - return vmx_handle_lds(regs); - } - gppa = (vadr & ((1UL << data->ps) - 1)) + - (data->ppn >> (data->ps - 12) << data->ps); - if (__gpfn_is_io(v->domain, gppa >> PAGE_SHIFT)) { - if (misr.sp) - panic_domain(NULL, "ld.s on I/O page not with UC attr." - " pte=0x%lx\n", data->page_flags); - if (data->pl >= ((regs->cr_ipsr >> IA64_PSR_CPL0_BIT) & 3)) - emulate_io_inst(v, gppa, data->ma); - else { - vcpu_set_isr(v, misr.val); - data_access_rights(v, vadr); - } - return IA64_FAULT; - } - } - thash_vhpt_insert(v, data->page_flags, data->itir, vadr, type); - - }else if(type == DSIDE_TLB){ - - if (misr.sp) - return vmx_handle_lds(regs); - - vcpu_get_rr(v, vadr, &rr); - itir = rr & (RR_RID_MASK | RR_PS_MASK); - - if(!vhpt_enabled(v, vadr, misr.rs?RSE_REF:DATA_REF)){ - if (GOS_WINDOWS(v)) { - /* windows use region 4 and 5 for identity mapping */ - if (REGION_NUMBER(vadr) == 4 && !(regs->cr_ipsr & IA64_PSR_CPL) - && (REGION_OFFSET(vadr)<= _PAGE_PPN_MASK)) { - - pteval = PAGEALIGN(REGION_OFFSET(vadr), itir_ps(itir)) | - (_PAGE_P | _PAGE_A | _PAGE_D | - _PAGE_MA_WB | _PAGE_AR_RW); - - if (thash_purge_and_insert(v, pteval, itir, vadr, type)) - goto try_again; - - return IA64_NO_FAULT; - } - - if (REGION_NUMBER(vadr) == 5 && !(regs->cr_ipsr & IA64_PSR_CPL) - && (REGION_OFFSET(vadr)<= _PAGE_PPN_MASK)) { - - pteval = PAGEALIGN(REGION_OFFSET(vadr),itir_ps(itir)) | - (_PAGE_P | _PAGE_A | _PAGE_D | - _PAGE_MA_UC | _PAGE_AR_RW); - - if (thash_purge_and_insert(v, pteval, itir, vadr, type)) - goto try_again; - - return IA64_NO_FAULT; - } - } - - if(vpsr.ic){ - vcpu_set_isr(v, misr.val); - alt_dtlb(v, vadr); - return IA64_FAULT; - } else{ - nested_dtlb(v); - return IA64_FAULT; - } - } - - vpta.val = vmx_vcpu_get_pta(v); - if (vpta.vf) { - /* Long format is not yet supported. */ - if (vpsr.ic) { - vcpu_set_isr(v, misr.val); - dtlb_fault(v, vadr); - return IA64_FAULT; - } else { - nested_dtlb(v); - return IA64_FAULT; - } - } - - /* avoid recursively walking (short format) VHPT */ - if (!GOS_WINDOWS(v) && - (((vadr ^ vpta.val) << 3) >> (vpta.size + 3)) == 0) { - - if (vpsr.ic) { - vcpu_set_isr(v, misr.val); - dtlb_fault(v, vadr); - return IA64_FAULT; - } else { - nested_dtlb(v); - return IA64_FAULT; - } - } - - vhpt_adr = vmx_vcpu_thash(v, vadr); - if (!guest_vhpt_lookup(vhpt_adr, &pteval)) { - /* VHPT successfully read. */ - if (!(pteval & _PAGE_P)) { - if (vpsr.ic) { - vcpu_set_isr(v, misr.val); - dtlb_fault(v, vadr); - return IA64_FAULT; - } else { - nested_dtlb(v); - return IA64_FAULT; - } - } else if ((pteval & _PAGE_MA_MASK) != _PAGE_MA_ST) { - thash_purge_and_insert(v, pteval, itir, vadr, DSIDE_TLB); - return IA64_NO_FAULT; - } else if (vpsr.ic) { - vcpu_set_isr(v, misr.val); - dtlb_fault(v, vadr); - return IA64_FAULT; - }else{ - nested_dtlb(v); - return IA64_FAULT; - } - } else { - /* Can't read VHPT. */ - if (vpsr.ic) { - vcpu_set_isr(v, misr.val); - dvhpt_fault(v, vadr); - return IA64_FAULT; - } else { - nested_dtlb(v); - return IA64_FAULT; - } - } - }else if(type == ISIDE_TLB){ - - if (!vpsr.ic) - misr.ni = 1; - if (!vhpt_enabled(v, vadr, INST_REF)) { - vcpu_set_isr(v, misr.val); - alt_itlb(v, vadr); - return IA64_FAULT; - } - - vpta.val = vmx_vcpu_get_pta(v); - if (vpta.vf) { - /* Long format is not yet supported. */ - vcpu_set_isr(v, misr.val); - itlb_fault(v, vadr); - return IA64_FAULT; - } - - - vhpt_adr = vmx_vcpu_thash(v, vadr); - if (!guest_vhpt_lookup(vhpt_adr, &pteval)) { - /* VHPT successfully read. */ - if (pteval & _PAGE_P) { - if ((pteval & _PAGE_MA_MASK) == _PAGE_MA_ST) { - vcpu_set_isr(v, misr.val); - itlb_fault(v, vadr); - return IA64_FAULT; - } - vcpu_get_rr(v, vadr, &rr); - itir = rr & (RR_RID_MASK | RR_PS_MASK); - thash_purge_and_insert(v, pteval, itir, vadr, ISIDE_TLB); - return IA64_NO_FAULT; - } else { - vcpu_set_isr(v, misr.val); - inst_page_not_present(v, vadr); - return IA64_FAULT; - } - } else { - vcpu_set_isr(v, misr.val); - ivhpt_fault(v, vadr); - return IA64_FAULT; - } - } - return IA64_NO_FAULT; -} diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/vmx/vmx_utility.c --- a/xen/arch/ia64/vmx/vmx_utility.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/vmx/vmx_utility.c Tue Jul 17 10:20:21 2007 +0100 @@ -26,7 +26,7 @@ #include <asm/processor.h> #include <asm/vmx_mm_def.h> - +#ifdef CHECK_FAULT /* * Return: * 0: Not reserved indirect registers @@ -71,6 +71,7 @@ is_reserved_indirect_register ( return 0; } +#endif /* * Return: @@ -207,7 +208,7 @@ check_psr_rsv_fields (u64 value) } - +#ifdef CHECK_FAULT /* * Return: * 1: CR reserved fields are not zero @@ -310,9 +311,9 @@ check_cr_rsv_fields (int index, u64 valu panic ("Unsupported CR"); return 0; } - - - +#endif + +#if 0 /* * Return: * 0: Indirect Reg reserved fields are not zero @@ -361,7 +362,7 @@ check_indirect_reg_rsv_fields ( int type return 1; } - +#endif diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/vmx/vmx_vcpu.c --- a/xen/arch/ia64/vmx/vmx_vcpu.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/vmx/vmx_vcpu.c Tue Jul 17 10:20:21 2007 +0100 @@ -96,8 +96,7 @@ vmx_vcpu_set_psr(VCPU *vcpu, unsigned lo */ VCPU(vcpu,vpsr) = value & (~ (IA64_PSR_ID |IA64_PSR_DA | IA64_PSR_DD | - IA64_PSR_SS | IA64_PSR_ED | IA64_PSR_IA - )); + IA64_PSR_ED | IA64_PSR_IA)); if ( !old_psr.i && (value & IA64_PSR_I) ) { // vpsr.i 0->1 diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/vmx/vmx_virt.c --- a/xen/arch/ia64/vmx/vmx_virt.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/vmx/vmx_virt.c Tue Jul 17 10:20:21 2007 +0100 @@ -178,8 +178,8 @@ static IA64FAULT vmx_emul_mov_to_psr(VCP { u64 val; - if(vcpu_get_gr_nat(vcpu, inst.M35.r2, &val) != IA64_NO_FAULT) - panic_domain(vcpu_regs(vcpu),"get_psr nat bit fault\n"); + if (vcpu_get_gr_nat(vcpu, inst.M35.r2, &val) != IA64_NO_FAULT) + panic_domain(vcpu_regs(vcpu),"get_psr nat bit fault\n"); return vmx_vcpu_set_psr_l(vcpu, val); } @@ -914,7 +914,6 @@ static IA64FAULT vmx_emul_mov_to_ibr(VCP static IA64FAULT vmx_emul_mov_to_ibr(VCPU *vcpu, INST64 inst) { u64 r3,r2; - return IA64_NO_FAULT; #ifdef CHECK_FAULT IA64_PSR vpsr; vpsr.val=vmx_vcpu_get_psr(vcpu); @@ -932,7 +931,7 @@ static IA64FAULT vmx_emul_mov_to_ibr(VCP return IA64_FAULT; #endif //CHECK_FAULT } - return (vmx_vcpu_set_ibr(vcpu,r3,r2)); + return vmx_vcpu_set_ibr(vcpu,r3,r2); } static IA64FAULT vmx_emul_mov_to_pmc(VCPU *vcpu, INST64 inst) @@ -1062,6 +1061,7 @@ static IA64FAULT vmx_emul_mov_from_dbr(V static IA64FAULT vmx_emul_mov_from_dbr(VCPU *vcpu, INST64 inst) { u64 r3,r1; + IA64FAULT res; #ifdef CHECK_FAULT if(check_target_register(vcpu, inst.M43.r1)){ set_illegal_op_isr(vcpu); @@ -1092,13 +1092,16 @@ static IA64FAULT vmx_emul_mov_from_dbr(V return IA64_FAULT; } #endif //CHECK_FAULT - r1 = vmx_vcpu_get_dbr(vcpu, r3); + res = vmx_vcpu_get_ibr(vcpu, r3, &r1); + if (res != IA64_NO_FAULT) + return res; return vcpu_set_gr(vcpu, inst.M43.r1, r1,0); } static IA64FAULT vmx_emul_mov_from_ibr(VCPU *vcpu, INST64 inst) { u64 r3,r1; + IA64FAULT res; #ifdef CHECK_FAULT if(check_target_register(vcpu, inst.M43.r1)){ set_illegal_op_isr(vcpu); @@ -1129,7 +1132,9 @@ static IA64FAULT vmx_emul_mov_from_ibr(V return IA64_FAULT; } #endif //CHECK_FAULT - r1 = vmx_vcpu_get_ibr(vcpu, r3); + res = vmx_vcpu_get_dbr(vcpu, r3, &r1); + if (res != IA64_NO_FAULT) + return res; return vcpu_set_gr(vcpu, inst.M43.r1, r1,0); } @@ -1562,21 +1567,37 @@ if ( (cause == 0xff && opcode == 0x1e000 break; case EVENT_VMSW: printk ("Unimplemented instruction %ld\n", cause); - status=IA64_FAULT; + status=IA64_FAULT; break; default: - panic_domain(regs,"unknown cause %ld, iip: %lx, ipsr: %lx\n", cause,regs->cr_iip,regs->cr_ipsr); + panic_domain(regs,"unknown cause %ld, iip: %lx, ipsr: %lx\n", + cause,regs->cr_iip,regs->cr_ipsr); break; }; #if 0 - if (status == IA64_FAULT) + if (status != IA64_NO_FAULT) panic("Emulation failed with cause %d:\n", cause); #endif - if ( status == IA64_NO_FAULT && cause !=EVENT_RFI ) { - vcpu_increment_iip(vcpu); - } + switch (status) { + case IA64_RSVDREG_FAULT: + set_rsv_reg_field_isr(vcpu); + rsv_reg_field(vcpu); + break; + case IA64_ILLOP_FAULT: + set_illegal_op_isr(vcpu); + illegal_op(vcpu); + break; + case IA64_FAULT: + /* Registers aleady set. */ + break; + case IA64_NO_FAULT: + if ( cause != EVENT_RFI ) + vcpu_increment_iip(vcpu); + break; + } + recover_if_physical_mode(vcpu); return; diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/xen/Makefile --- a/xen/arch/ia64/xen/Makefile Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/xen/Makefile Tue Jul 17 10:20:21 2007 +0100 @@ -10,6 +10,7 @@ obj-y += dom_fw_dom0.o obj-y += dom_fw_dom0.o obj-y += dom_fw_domu.o obj-y += dom_fw_utils.o +obj-y += dom_fw_sn2.o obj-y += fw_emul.o obj-y += hpsimserial.o obj-y += hypercall.o diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/xen/dom0_ops.c --- a/xen/arch/ia64/xen/dom0_ops.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/xen/dom0_ops.c Tue Jul 17 10:20:21 2007 +0100 @@ -224,12 +224,6 @@ long arch_do_domctl(xen_domctl_t *op, XE return ret; } -/* - * Temporarily disable the NUMA PHYSINFO code until the rest of the - * changes are upstream. - */ -#undef IA64_NUMA_PHYSINFO - long arch_do_sysctl(xen_sysctl_t *op, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl) { long ret = 0; @@ -238,46 +232,47 @@ long arch_do_sysctl(xen_sysctl_t *op, XE { case XEN_SYSCTL_physinfo: { -#ifdef IA64_NUMA_PHYSINFO - int i; - uint32_t *map, cpu_to_node_map[NR_CPUS]; -#endif + int i, node_cpus = 0; + uint32_t max_array_ent; xen_sysctl_physinfo_t *pi = &op->u.physinfo; - pi->threads_per_core = - cpus_weight(cpu_sibling_map[0]); + pi->threads_per_core = cpus_weight(cpu_sibling_map[0]); pi->cores_per_socket = cpus_weight(cpu_core_map[0]) / pi->threads_per_core; pi->nr_nodes = num_online_nodes(); - pi->sockets_per_node = num_online_cpus() / - (pi->nr_nodes * pi->cores_per_socket * pi->threads_per_core); + + /* + * Guess at a sockets_per_node value. Use the maximum number of + * CPUs per node to avoid deconfigured CPUs breaking the average. + */ + for_each_online_node(i) + node_cpus = max(node_cpus, cpus_weight(node_to_cpumask(i))); + + pi->sockets_per_node = node_cpus / + (pi->cores_per_socket * pi->threads_per_core); + pi->total_pages = total_pages; pi->free_pages = avail_domheap_pages(); pi->scrub_pages = avail_scrub_pages(); pi->cpu_khz = local_cpu_data->proc_freq / 1000; memset(pi->hw_cap, 0, sizeof(pi->hw_cap)); - //memcpy(pi->hw_cap, boot_cpu_data.x86_capability, NCAPINTS*4); + + max_array_ent = pi->max_cpu_id; + pi->max_cpu_id = last_cpu(cpu_online_map); + max_array_ent = min_t(uint32_t, max_array_ent, pi->max_cpu_id); + ret = 0; -#ifdef IA64_NUMA_PHYSINFO - /* fetch cpu_to_node pointer from guest */ - get_xen_guest_handle(map, pi->cpu_to_node); - - /* if set, fill out cpu_to_node array */ - if (map != NULL) { - /* copy cpu to node mapping to domU */ - memset(cpu_to_node_map, 0, sizeof(cpu_to_node_map)); - for (i = 0; i < num_online_cpus(); i++) { - cpu_to_node_map[i] = cpu_to_node(i); - if (copy_to_guest_offset(pi->cpu_to_node, i, - &(cpu_to_node_map[i]), 1)) { + if (!guest_handle_is_null(pi->cpu_to_node)) { + for (i = 0; i <= max_array_ent; i++) { + uint32_t node = cpu_online(i) ? cpu_to_node(i) : ~0u; + if (copy_to_guest_offset(pi->cpu_to_node, i, &node, 1)) { ret = -EFAULT; break; } } } -#endif if ( copy_to_guest(u_sysctl, op, 1) ) ret = -EFAULT; diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/xen/dom_fw_sn2.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/arch/ia64/xen/dom_fw_sn2.c Tue Jul 17 10:20:21 2007 +0100 @@ -0,0 +1,92 @@ +/* + * Xen domain0 platform firmware fixups for sn2 + * Copyright (C) 2007 Silicon Graphics Inc. + * Jes Sorensen <jes@xxxxxxx> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2. + * + * This program 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 General Public License for more details. + * + * 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> +#include <xen/acpi.h> +#include <xen/errno.h> +#include <xen/sched.h> +#include <xen/nodemask.h> + +#include <asm/dom_fw.h> +#include <asm/dom_fw_common.h> +#include <asm/dom_fw_dom0.h> +#include <asm/dom_fw_utils.h> + +#include <asm/sn/arch.h> +#include <asm/sn/addrs.h> +#include <asm/sn/shub_mmr.h> + +#define SWAP_NASID(n, x) ((x & ~NASID_MASK) | NASID_SPACE(n)) + +int __init +sn2_dom_fw_init(domain_t *d, + struct xen_ia64_boot_param *bp, + struct fw_tables *tables) +{ + int node; + short nasid; + unsigned long shubid, shubpicam, shubpiowrite; + + printk("SN2 mapping specific registers to dom0\n"); + + assign_domain_mach_page(d, LOCAL_MMR_OFFSET | SH_RTC, PAGE_SIZE, + ASSIGN_nocache); + + if (is_shub1()) { + /* 0x110060000 */ + shubid = SH1_GLOBAL_MMR_OFFSET + (SH1_SHUB_ID & PAGE_MASK); + /* 0x120050000 */ + shubpicam = SH1_GLOBAL_MMR_OFFSET + + (SH1_PI_CAM_CONTROL & PAGE_MASK); + /* 0x120070000 */ + shubpiowrite = SH1_GLOBAL_MMR_OFFSET + + (SH1_PIO_WRITE_STATUS_0 & PAGE_MASK); + + for_each_online_node(node) { + nasid = cnodeid_to_nasid(node); + shubid = SWAP_NASID(nasid, shubid); + shubpicam = SWAP_NASID(nasid, shubpicam); + shubpiowrite = SWAP_NASID(nasid, shubpiowrite); + + assign_domain_mach_page(d, shubid, PAGE_SIZE, + ASSIGN_nocache); + assign_domain_mach_page(d, shubpicam, PAGE_SIZE, + ASSIGN_nocache); + assign_domain_mach_page(d, shubpiowrite, PAGE_SIZE, + ASSIGN_nocache); + } + + /* map leds */ + assign_domain_mach_page(d, LOCAL_MMR_OFFSET | + SH1_REAL_JUNK_BUS_LED0, + PAGE_SIZE, ASSIGN_nocache); + assign_domain_mach_page(d, LOCAL_MMR_OFFSET | + SH1_REAL_JUNK_BUS_LED1, + PAGE_SIZE, ASSIGN_nocache); + assign_domain_mach_page(d, LOCAL_MMR_OFFSET | + SH1_REAL_JUNK_BUS_LED2, + PAGE_SIZE, ASSIGN_nocache); + assign_domain_mach_page(d, LOCAL_MMR_OFFSET | + SH1_REAL_JUNK_BUS_LED3, + PAGE_SIZE, ASSIGN_nocache); + } else + panic("Unable to build EFI entry for SHUB 2 MMR\n"); + + return 0; +} diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/xen/dom_fw_utils.c --- a/xen/arch/ia64/xen/dom_fw_utils.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/xen/dom_fw_utils.c Tue Jul 17 10:20:21 2007 +0100 @@ -52,7 +52,6 @@ int xen_ia64_is_vcpu_allocated(struct do int xen_ia64_is_running_on_sim(struct domain *unused) { - extern unsigned long running_on_sim; return running_on_sim; } @@ -251,10 +250,28 @@ int dom_fw_setup(domain_t * d, unsigned imva_hypercall_base = (unsigned long)domain_mpa_to_imva (d, FW_HYPERCALL_BASE_PADDR); + /* + * dom_fw_init() + * - [FW_HYPERCALL_BASE_PADDR, FW_HYPERCALL_END_PADDR) + * - [FW_ACPI_BASE_PADDR, FW_ACPI_END_PADDR) + * - [FW_TABLES_BASE_PADDR, tables->fw_tables_end_paddr) + * + * complete_dom0_memmap() for dom0 + * - real machine memory map + * - memmap_info by setup_dom0_memmap_info() + * + * complete_domu_memmap() for old domu builder + * - I/O port + * - conventional memory + * - memmap_info + */ +#define NUM_EXTRA_MEM_DESCS 4 + /* Estimate necessary efi memmap size and allocate memory */ fw_tables_size = sizeof(*fw_tables) + (ia64_boot_param->efi_memmap_size / - ia64_boot_param->efi_memdesc_size + NUM_MEM_DESCS) * + ia64_boot_param->efi_memdesc_size + + NUM_EXTRA_MEM_DESCS) * sizeof(fw_tables->efi_memmap[0]); if (fw_tables_size < FW_TABLES_END_PADDR_MIN - FW_TABLES_BASE_PADDR) @@ -292,14 +309,22 @@ int dom_fw_setup(domain_t * d, unsigned xfree(fw_tables); return ret; } + + ret = platform_fw_init(d, bp, fw_tables); + if (ret < 0) { + xfree(fw_tables); + return ret; + } + if (sizeof(*fw_tables) + fw_tables->num_mds * sizeof(fw_tables->efi_memmap[0]) > fw_tables_size) { - panic("EFI memmap too large. Increase NUM_MEM_DESCS.\n" + panic("EFI memmap too large. " + "Increase NUM_EXTRA_MEM_DESCS.\n" "fw_table_size %ld > %ld num_mds %ld " - "NUM_MEM_DESCS %d.\n", + "NUM_EXTRA_MEM_DESCS %d.\n", fw_tables_size, fw_tables->fw_tables_size, - fw_tables->num_mds, NUM_MEM_DESCS); + fw_tables->num_mds, NUM_EXTRA_MEM_DESCS); } fw_tables_size = sizeof(*fw_tables) + fw_tables->num_mds * sizeof(fw_tables->efi_memmap[0]); diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/xen/domain.c --- a/xen/arch/ia64/xen/domain.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/xen/domain.c Tue Jul 17 10:20:21 2007 +0100 @@ -58,8 +58,6 @@ static unsigned int __initdata dom0_max_ static unsigned int __initdata dom0_max_vcpus = 1; integer_param("dom0_max_vcpus", dom0_max_vcpus); -extern unsigned long running_on_sim; - extern char dom0_command_line[]; /* forward declaration */ @@ -237,6 +235,14 @@ void context_switch(struct vcpu *prev, s ia64_disable_vhpt_walker(); lazy_fp_switch(prev, current); + if (prev->arch.dbg_used || next->arch.dbg_used) { + /* + * Load debug registers either because they are valid or to clear + * the previous one. + */ + ia64_load_debug_regs(next->arch.dbr); + } + prev = ia64_switch_to(next); /* Note: ia64_switch_to does not return here at vcpu initialization. */ @@ -361,10 +367,6 @@ void startup_cpu_idle_loop(void) # error "XMAPPEDREGS_SHIFT doesn't match sizeof(mapped_regs_t)." #endif -#if (IA64_RBS_OFFSET % 512) != IA64_GUEST_CONTEXT_RBS_OFFSET -# error "arch-ia64.h: IA64_GUEST_CONTEXT_RBS_OFFSET must be adjusted." -#endif - void hlt_timer_fn(void *data) { struct vcpu *v = data; @@ -607,6 +609,8 @@ int arch_vcpu_reset(struct vcpu *v) /* FIXME: Stub for now */ return 0; } + +#define COPY_FPREG(dst, src) memcpy(dst, src, sizeof(struct ia64_fpreg)) void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c) { @@ -674,12 +678,12 @@ void arch_get_info_guest(struct vcpu *v, c.nat->regs.ar.ccv = uregs->ar_ccv; - c.nat->regs.f[6] = uregs->f6; - c.nat->regs.f[7] = uregs->f7; - c.nat->regs.f[8] = uregs->f8; - c.nat->regs.f[9] = uregs->f9; - c.nat->regs.f[10] = uregs->f10; - c.nat->regs.f[11] = uregs->f11; + COPY_FPREG(&c.nat->regs.f[6], &uregs->f6); + COPY_FPREG(&c.nat->regs.f[7], &uregs->f7); + COPY_FPREG(&c.nat->regs.f[8], &uregs->f8); + COPY_FPREG(&c.nat->regs.f[9], &uregs->f9); + COPY_FPREG(&c.nat->regs.f[10], &uregs->f10); + COPY_FPREG(&c.nat->regs.f[11], &uregs->f11); c.nat->regs.r[4] = uregs->r4; c.nat->regs.r[5] = uregs->r5; @@ -689,11 +693,20 @@ void arch_get_info_guest(struct vcpu *v, /* FIXME: to be reordered. */ c.nat->regs.nats = uregs->eml_unat; + c.nat->regs.rbs_voff = (IA64_RBS_OFFSET / 8) % 64; if (rbs_size < sizeof (c.nat->regs.rbs)) - memcpy (c.nat->regs.rbs, (char *)v + IA64_RBS_OFFSET, rbs_size); + memcpy(c.nat->regs.rbs, (char *)v + IA64_RBS_OFFSET, rbs_size); c.nat->privregs_pfn = get_gpfn_from_mfn (virt_to_maddr(v->arch.privregs) >> PAGE_SHIFT); + + for (i = 0; i < IA64_NUM_DBG_REGS; i++) { + vcpu_get_dbr(v, i, &c.nat->regs.dbr[i]); + vcpu_get_ibr(v, i, &c.nat->regs.ibr[i]); + } + + for (i = 0; i < 7; i++) + vcpu_get_rr(v, (unsigned long)i << 61, &c.nat->regs.rr[i]); /* Fill extra regs. */ for (i = 0; i < 8; i++) { @@ -724,7 +737,7 @@ int arch_set_info_guest(struct vcpu *v, struct domain *d = v->domain; int was_initialised = v->is_initialised; unsigned int rbs_size; - int rc; + int rc, i; /* Finish vcpu initialization. */ if (!was_initialised) { @@ -777,7 +790,7 @@ int arch_set_info_guest(struct vcpu *v, if (!was_initialised) uregs->loadrs = (rbs_size) << 16; if (rbs_size == (uregs->loadrs >> 16)) - memcpy ((char *)v + IA64_RBS_OFFSET, c.nat->regs.rbs, rbs_size); + memcpy((char *)v + IA64_RBS_OFFSET, c.nat->regs.rbs, rbs_size); uregs->r1 = c.nat->regs.r[1]; uregs->r12 = c.nat->regs.r[12]; @@ -807,12 +820,12 @@ int arch_set_info_guest(struct vcpu *v, uregs->ar_ccv = c.nat->regs.ar.ccv; - uregs->f6 = c.nat->regs.f[6]; - uregs->f7 = c.nat->regs.f[7]; - uregs->f8 = c.nat->regs.f[8]; - uregs->f9 = c.nat->regs.f[9]; - uregs->f10 = c.nat->regs.f[10]; - uregs->f11 = c.nat->regs.f[11]; + COPY_FPREG(&uregs->f6, &c.nat->regs.f[6]); + COPY_FPREG(&uregs->f7, &c.nat->regs.f[7]); + COPY_FPREG(&uregs->f8, &c.nat->regs.f[8]); + COPY_FPREG(&uregs->f9, &c.nat->regs.f[9]); + COPY_FPREG(&uregs->f10, &c.nat->regs.f[10]); + COPY_FPREG(&uregs->f11, &c.nat->regs.f[11]); uregs->r4 = c.nat->regs.r[4]; uregs->r5 = c.nat->regs.r[5]; @@ -825,12 +838,17 @@ int arch_set_info_guest(struct vcpu *v, if (!d->arch.is_vti) { /* domain runs at PL2/3 */ - uregs->cr_ipsr |= 2UL << IA64_PSR_CPL0_BIT; - uregs->ar_rsc |= (2 << 2); /* force PL2/3 */ + uregs->cr_ipsr = vcpu_pl_adjust(uregs->cr_ipsr, + IA64_PSR_CPL0_BIT); + uregs->ar_rsc = vcpu_pl_adjust(uregs->ar_rsc, 2); } + for (i = 0; i < IA64_NUM_DBG_REGS; i++) { + vcpu_set_dbr(v, i, c.nat->regs.dbr[i]); + vcpu_set_ibr(v, i, c.nat->regs.ibr[i]); + } + if (c.nat->flags & VGCF_EXTRA_REGS) { - int i; struct vcpu_tr_regs *tr = &c.nat->regs.tr; for (i = 0; i < 8; i++) { @@ -1497,3 +1515,48 @@ static void __init parse_dom0_mem(char * dom0_size = parse_size_and_unit(s, NULL); } custom_param("dom0_mem", parse_dom0_mem); + +/* + * Helper function for the optimization stuff handling the identity mapping + * feature. + */ +static inline void +optf_set_identity_mapping(unsigned long* mask, struct identity_mapping* im, + struct xen_ia64_opt_feature* f) +{ + if (f->on) { + *mask |= f->cmd; + im->pgprot = f->pgprot; + im->key = f->key; + } else { + *mask &= ~(f->cmd); + im->pgprot = 0; + im->key = 0; + } +} + +/* Switch a optimization feature on/off. */ +int +domain_opt_feature(struct xen_ia64_opt_feature* f) +{ + struct opt_feature* optf = &(current->domain->arch.opt_feature); + long rc = 0; + + switch (f->cmd) { + case XEN_IA64_OPTF_IDENT_MAP_REG4: + optf_set_identity_mapping(&optf->mask, &optf->im_reg4, f); + break; + case XEN_IA64_OPTF_IDENT_MAP_REG5: + optf_set_identity_mapping(&optf->mask, &optf->im_reg5, f); + break; + case XEN_IA64_OPTF_IDENT_MAP_REG7: + optf_set_identity_mapping(&optf->mask, &optf->im_reg7, f); + break; + default: + printk("%s: unknown opt_feature: %ld\n", __func__, f->cmd); + rc = -ENOSYS; + break; + } + return rc; +} + diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/xen/faults.c --- a/xen/arch/ia64/xen/faults.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/xen/faults.c Tue Jul 17 10:20:21 2007 +0100 @@ -38,10 +38,9 @@ extern int ia64_hyperprivop(unsigned lon extern int ia64_hyperprivop(unsigned long, REGS *); extern IA64FAULT ia64_hypercall(struct pt_regs *regs); -#define IA64_PSR_CPL1 (__IA64_UL(1) << IA64_PSR_CPL1_BIT) // note IA64_PSR_PK removed from following, why is this necessary? #define DELIVER_PSR_SET (IA64_PSR_IC | IA64_PSR_I | \ - IA64_PSR_DT | IA64_PSR_RT | IA64_PSR_CPL1 | \ + IA64_PSR_DT | IA64_PSR_RT | \ IA64_PSR_IT | IA64_PSR_BN) #define DELIVER_PSR_CLR (IA64_PSR_AC | IA64_PSR_DFL | IA64_PSR_DFH | \ @@ -92,6 +91,7 @@ static void reflect_interruption(unsigne regs->cr_iip = ((unsigned long)PSCBX(v, iva) + vector) & ~0xffUL; regs->cr_ipsr = (regs->cr_ipsr & ~DELIVER_PSR_CLR) | DELIVER_PSR_SET; + regs->cr_ipsr = vcpu_pl_adjust(regs->cr_ipsr, IA64_PSR_CPL0_BIT); if (PSCB(v, dcr) & IA64_DCR_BE) regs->cr_ipsr |= IA64_PSR_BE; @@ -137,6 +137,7 @@ void reflect_event(void) regs->cr_iip = v->arch.event_callback_ip; regs->cr_ipsr = (regs->cr_ipsr & ~DELIVER_PSR_CLR) | DELIVER_PSR_SET; + regs->cr_ipsr = vcpu_pl_adjust(regs->cr_ipsr, IA64_PSR_CPL0_BIT); if (PSCB(v, dcr) & IA64_DCR_BE) regs->cr_ipsr |= IA64_PSR_BE; @@ -236,6 +237,8 @@ void ia64_do_page_fault(unsigned long ad ((unsigned long)PSCBX(current, iva) + fault) & ~0xffUL; regs->cr_ipsr = (regs->cr_ipsr & ~DELIVER_PSR_CLR) | DELIVER_PSR_SET; + regs->cr_ipsr = vcpu_pl_adjust(regs->cr_ipsr, + IA64_PSR_CPL0_BIT); if (PSCB(current, hpsr_dfh)) regs->cr_ipsr |= IA64_PSR_DFH; @@ -488,8 +491,6 @@ ia64_fault(unsigned long vector, unsigne panic("Fault in Xen.\n"); } -unsigned long running_on_sim = 0; - /* Also read in hyperprivop.S */ int first_break = 0; @@ -503,7 +504,7 @@ ia64_handle_break(unsigned long ifa, str /* FIXME: don't hardcode constant */ if ((iim == 0x80001 || iim == 0x80002) - && ia64_get_cpl(regs->cr_ipsr) == 2) { + && ia64_get_cpl(regs->cr_ipsr) == CONFIG_CPL0_EMUL) { do_ssc(vcpu_get_gr(current, 36), regs); } #ifdef CRASH_DEBUG @@ -513,7 +514,8 @@ ia64_handle_break(unsigned long ifa, str debugger_trap_fatal(0 /* don't care */ , regs); } #endif - else if (iim == d->arch.breakimm && ia64_get_cpl(regs->cr_ipsr) == 2) { + else if (iim == d->arch.breakimm && + ia64_get_cpl(regs->cr_ipsr) == CONFIG_CPL0_EMUL) { /* by default, do not continue */ v->arch.hypercall_continuation = 0; @@ -523,7 +525,7 @@ ia64_handle_break(unsigned long ifa, str } else reflect_interruption(isr, regs, vector); } else if ((iim - HYPERPRIVOP_START) < HYPERPRIVOP_MAX - && ia64_get_cpl(regs->cr_ipsr) == 2) { + && ia64_get_cpl(regs->cr_ipsr) == CONFIG_CPL0_EMUL) { if (ia64_hyperprivop(iim, regs)) vcpu_increment_iip(current); } else { @@ -544,6 +546,14 @@ ia64_handle_privop(unsigned long ifa, st if (vector != IA64_NO_FAULT && vector != IA64_RFI_IN_PROGRESS) { // Note: if a path results in a vector to reflect that requires // iha/itir (e.g. vcpu_force_data_miss), they must be set there + /* + * IA64_GENEX_VECTOR may contain in the lowest byte an ISR.code + * see IA64_ILLOP_FAULT, ... + */ + if ((vector & ~0xffUL) == IA64_GENEX_VECTOR) { + isr = vector & 0xffUL; + vector = IA64_GENEX_VECTOR; + } reflect_interruption(isr, regs, vector); } } @@ -639,6 +649,11 @@ ia64_handle_reflection(unsigned long ifa PSCB(current, iim) = iim; vector = IA64_SPECULATION_VECTOR; break; + case 29: + vector = IA64_DEBUG_VECTOR; + if (debugger_trap_entry(vector,regs)) + return; + break; case 30: // FIXME: Should we handle unaligned refs in Xen?? vector = IA64_UNALIGNED_REF_VECTOR; @@ -673,19 +688,19 @@ ia64_handle_reflection(unsigned long ifa vector = IA64_LOWERPRIV_TRANSFER_TRAP_VECTOR; break; case 35: - printk("ia64_handle_reflection: handling taken branch trap\n"); vector = IA64_TAKEN_BRANCH_TRAP_VECTOR; + if (debugger_trap_entry(vector,regs)) + return; break; case 36: - printk("ia64_handle_reflection: handling single step trap\n"); vector = IA64_SINGLE_STEP_TRAP_VECTOR; + if (debugger_trap_entry(vector,regs)) + return; break; default: - printk("ia64_handle_reflection: unhandled vector=0x%lx\n", - vector); - while (vector) - /* spin */; + panic_domain(regs, "ia64_handle_reflection: " + "unhandled vector=0x%lx\n", vector); return; } if (check_lazy_cover && (isr & IA64_ISR_IR) && diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/xen/fw_emul.c --- a/xen/arch/ia64/xen/fw_emul.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/xen/fw_emul.c Tue Jul 17 10:20:21 2007 +0100 @@ -23,6 +23,7 @@ #include <asm/pal.h> #include <asm/sal.h> #include <asm/sn/sn_sal.h> +#include <asm/sn/hubdev.h> #include <asm/xenmca.h> #include <public/sched.h> @@ -37,8 +38,6 @@ #include <xen/time.h> static DEFINE_SPINLOCK(efi_time_services_lock); - -extern unsigned long running_on_sim; struct sal_mc_params { u64 param_type; @@ -141,7 +140,7 @@ sal_emulator (long index, unsigned long status = 0; switch (index) { case SAL_FREQ_BASE: - if (!running_on_sim) + if (likely(!running_on_sim)) status = ia64_sal_freq_base(in1,&r9,&r10); else switch (in1) { case SAL_FREQ_BASE_PLATFORM: @@ -380,7 +379,7 @@ sal_emulator (long index, unsigned long case SN_SAL_GET_MASTER_NASID: status = -1; if (current->domain == dom0) { - printk("*** Emulating SN_SAL_GET_MASTER_NASID ***\n"); + /* printk("*** Emulating SN_SAL_GET_MASTER_NASID ***\n"); */ SAL_CALL_NOLOCK(ret_stuff, SN_SAL_GET_MASTER_NASID, 0, 0, 0, 0, 0, 0, 0); status = ret_stuff.status; @@ -392,7 +391,7 @@ sal_emulator (long index, unsigned long case SN_SAL_GET_KLCONFIG_ADDR: status = -1; if (current->domain == dom0) { - printk("*** Emulating SN_SAL_GET_KLCONFIG_ADDR ***\n"); + /* printk("*** Emulating SN_SAL_GET_KLCONFIG_ADDR ***\n"); */ SAL_CALL_NOLOCK(ret_stuff, SN_SAL_GET_KLCONFIG_ADDR, in1, 0, 0, 0, 0, 0, 0); status = ret_stuff.status; @@ -404,9 +403,9 @@ sal_emulator (long index, unsigned long case SN_SAL_GET_SAPIC_INFO: status = -1; if (current->domain == dom0) { - printk("*** Emulating SN_SAL_GET_SAPIC_INFO ***\n"); - SAL_CALL_NOLOCK(ret_stuff, SN_SAL_GET_SAPIC_INFO, in1, - 0, 0, 0, 0, 0, 0); + /* printk("*** Emulating SN_SAL_GET_SAPIC_INFO ***\n"); */ + SAL_CALL_NOLOCK(ret_stuff, SN_SAL_GET_SAPIC_INFO, + in1, 0, 0, 0, 0, 0, 0); status = ret_stuff.status; r9 = ret_stuff.v0; r10 = ret_stuff.v1; @@ -416,9 +415,9 @@ sal_emulator (long index, unsigned long case SN_SAL_GET_SN_INFO: status = -1; if (current->domain == dom0) { - printk("*** Emulating SN_SAL_GET_SN_INFO ***\n"); - SAL_CALL_NOLOCK(ret_stuff, SN_SAL_GET_SN_INFO, in1, - 0, 0, 0, 0, 0, 0); + /* printk("*** Emulating SN_SAL_GET_SN_INFO ***\n"); */ + SAL_CALL_NOLOCK(ret_stuff, SN_SAL_GET_SN_INFO, + in1, 0, 0, 0, 0, 0, 0); status = ret_stuff.status; r9 = ret_stuff.v0; r10 = ret_stuff.v1; @@ -428,9 +427,124 @@ sal_emulator (long index, unsigned long case SN_SAL_IOIF_GET_HUBDEV_INFO: status = -1; if (current->domain == dom0) { - printk("*** Emulating SN_SAL_IOIF_GET_HUBDEV_INFO ***\n"); + /* printk("*** Emulating SN_SAL_IOIF_GET_HUBDEV_INFO ***\n"); */ SAL_CALL_NOLOCK(ret_stuff, SN_SAL_IOIF_GET_HUBDEV_INFO, in1, in2, 0, 0, 0, 0, 0); + status = ret_stuff.status; + r9 = ret_stuff.v0; + r10 = ret_stuff.v1; + r11 = ret_stuff.v2; + } + break; + case SN_SAL_IOIF_INIT: + status = -1; + if (current->domain == dom0) { + /* printk("*** Emulating SN_SAL_IOIF_INIT ***\n"); */ + SAL_CALL_NOLOCK(ret_stuff, SN_SAL_IOIF_INIT, + 0, 0, 0, 0, 0, 0, 0); + status = ret_stuff.status; + r9 = ret_stuff.v0; + r10 = ret_stuff.v1; + r11 = ret_stuff.v2; + } + break; + case SN_SAL_GET_PROM_FEATURE_SET: + status = -1; + if (current->domain == dom0) { + /* printk("*** Emulating SN_SAL_GET_PROM_FEATURE_SET ***\n"); */ + SAL_CALL_NOLOCK(ret_stuff, SN_SAL_GET_PROM_FEATURE_SET, + in1, 0, 0, 0, 0, 0, 0); + status = ret_stuff.status; + r9 = ret_stuff.v0; + r10 = ret_stuff.v1; + r11 = ret_stuff.v2; + } + break; + case SN_SAL_SET_OS_FEATURE_SET: + status = -1; + if (current->domain == dom0) { + /* printk("*** Emulating SN_SAL_SET_OS_FEATURE_SET ***\n"); */ + SAL_CALL_NOLOCK(ret_stuff, SN_SAL_SET_OS_FEATURE_SET, + in1, 0, 0, 0, 0, 0, 0); + status = ret_stuff.status; + r9 = ret_stuff.v0; + r10 = ret_stuff.v1; + r11 = ret_stuff.v2; + } + break; + case SN_SAL_SET_ERROR_HANDLING_FEATURES: + status = -1; + if (current->domain == dom0) { + /* printk("*** Emulating SN_SAL_SET_ERROR_HANDLING_FEATURES ***\n"); */ + SAL_CALL_NOLOCK(ret_stuff, + SN_SAL_SET_ERROR_HANDLING_FEATURES, + in1, 0, 0, 0, 0, 0, 0); + status = ret_stuff.status; + r9 = ret_stuff.v0; + r10 = ret_stuff.v1; + r11 = ret_stuff.v2; + } + break; +#if 0 +/* + * Somehow ACPI breaks if allowing this one + */ + case SN_SAL_SET_CPU_NUMBER: + status = -1; + if (current->domain == dom0) { + printk("*** Emulating SN_SAL_SET_CPU_NUMBER ***\n"); + SAL_CALL_NOLOCK(ret_stuff, SN_SAL_SET_CPU_NUMBER, + in1, 0, 0, 0, 0, 0, 0); + status = ret_stuff.status; + r9 = ret_stuff.v0; + r10 = ret_stuff.v1; + r11 = ret_stuff.v2; + } + break; +#endif + case SN_SAL_LOG_CE: + status = -1; + if (current->domain == dom0) { + static int log_ce = 0; + if (!log_ce) { + printk("*** Emulating SN_SAL_LOG_CE *** " + " this will only be printed once\n"); + log_ce = 1; + } + SAL_CALL_NOLOCK(ret_stuff, SN_SAL_LOG_CE, + 0, 0, 0, 0, 0, 0, 0); + status = ret_stuff.status; + r9 = ret_stuff.v0; + r10 = ret_stuff.v1; + r11 = ret_stuff.v2; + } + break; + case SN_SAL_IOIF_GET_DEVICE_DMAFLUSH_LIST: + status = -1; + if (current->domain == dom0) { + struct sn_flush_device_common flush; + int flush_size; + + flush_size = sizeof(struct sn_flush_device_common); + memset(&flush, 0, flush_size); + SAL_CALL_NOLOCK(ret_stuff, + SN_SAL_IOIF_GET_DEVICE_DMAFLUSH_LIST, + in1, in2, in3, &flush, 0, 0, 0); +#if 0 + printk("*** Emulating " + "SN_SAL_IOIF_GET_DEVICE_DMAFLUSH_LIST ***\n"); +#endif + if (ret_stuff.status == SALRET_OK) { + XEN_GUEST_HANDLE(void) handle = + *(XEN_GUEST_HANDLE(void)*)&in4; + if (copy_to_guest(handle, &flush, 1)) { + printk("SN_SAL_IOIF_GET_DEVICE_" + "DMAFLUSH_LIST can't copy " + "to user!\n"); + ret_stuff.status = SALRET_ERROR; + } + } + status = ret_stuff.status; r9 = ret_stuff.v0; r10 = ret_stuff.v1; @@ -478,7 +592,7 @@ xen_pal_emulator(unsigned long index, u6 unsigned long flags; int processor; - if (running_on_sim) + if (unlikely(running_on_sim)) return pal_emulator_static(index); // pal code must be mapped by a TR when pal is called, however @@ -1259,7 +1373,10 @@ do_ssc(unsigned long ssc, struct pt_regs break; case SSC_OPEN: arg1 = vcpu_get_gr(current,33); // access rights -if (!running_on_sim) { printk("SSC_OPEN, not implemented on hardware. (ignoring...)\n"); arg0 = 0; } + if (!running_on_sim) { + printk("SSC_OPEN, not implemented on hardware. (ignoring...)\n"); + arg0 = 0; + } if (arg0) { // metaphysical address arg0 = translate_domain_mpaddr(arg0, NULL); retval = ia64_ssc(arg0,arg1,0,0,ssc); @@ -1320,7 +1437,10 @@ if (!running_on_sim) { printk("SSC_OPEN, arg1 = vcpu_get_gr(current,33); arg2 = vcpu_get_gr(current,34); arg3 = vcpu_get_gr(current,35); - if (!running_on_sim) { printk("SSC_CONNECT_INTERRUPT, not implemented on hardware. (ignoring...)\n"); break; } + if (!running_on_sim) { + printk("SSC_CONNECT_INTERRUPT, not implemented on hardware. (ignoring...)\n"); + break; + } (void)ia64_ssc(arg0,arg1,arg2,arg3,ssc); break; case SSC_NETDEV_PROBE: diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/xen/hypercall.c --- a/xen/arch/ia64/xen/hypercall.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/xen/hypercall.c Tue Jul 17 10:20:21 2007 +0100 @@ -224,6 +224,16 @@ ia64_hypercall(struct pt_regs *regs) regs->r10 = fpswa_ret.err1; regs->r11 = fpswa_ret.err2; break; + case __HYPERVISOR_opt_feature: { + XEN_GUEST_HANDLE(void) arg; + struct xen_ia64_opt_feature optf; + set_xen_guest_handle(arg, (void*)(vcpu_get_gr(v, 32))); + if (copy_from_guest(&optf, arg, 1) == 0) + regs->r8 = domain_opt_feature(&optf); + else + regs->r8 = -EFAULT; + break; + } default: printk("unknown ia64 fw hypercall %lx\n", regs->r2); regs->r8 = do_ni_hypercall(); diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/xen/hyperprivop.S --- a/xen/arch/ia64/xen/hyperprivop.S Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/xen/hyperprivop.S Tue Jul 17 10:20:21 2007 +0100 @@ -18,9 +18,8 @@ #define _PAGE_PPN_MASK 0x0003fffffffff000 //asm/pgtable.h doesn't do assembly -#define PAGE_PHYS 0x0010000000000761 //__pgprot(__DIRTY_BITS| - // _PAGE_PL_2|_PAGE_AR_RWX) -#define _PAGE_PL_2 (2<<7) +#define PAGE_PHYS (0x0010000000000661 | _PAGE_PL_PRIV) + //__pgprot(__DIRTY_BITS|_PAGE_PL_PRIV|_PAGE_AR_RWX) #if 1 // change to 0 to turn off all fast paths # define FAST_HYPERPRIVOPS @@ -62,7 +61,7 @@ #define IA64_PSR_CPL0 (__IA64_UL(1) << IA64_PSR_CPL0_BIT) // note IA64_PSR_PK removed from following, why is this necessary? #define DELIVER_PSR_SET (IA64_PSR_IC | IA64_PSR_I | \ - IA64_PSR_DT | IA64_PSR_RT | IA64_PSR_CPL1 | \ + IA64_PSR_DT | IA64_PSR_RT | \ IA64_PSR_IT | IA64_PSR_BN) #define DELIVER_PSR_CLR (IA64_PSR_AC | IA64_PSR_DFL | IA64_PSR_DFH | \ @@ -249,8 +248,8 @@ ENTRY(hyper_ssm_i) mov r29=r30 ;; movl r28=DELIVER_PSR_SET;; movl r27=~DELIVER_PSR_CLR;; + and r29=r29,r27;; or r29=r29,r28;; - and r29=r29,r27;; // set hpsr_dfh to ipsr adds r28=XSI_HPSR_DFH_OFS-XSI_PSR_IC_OFS,r18;; ld1 r28=[r28];; @@ -258,8 +257,7 @@ ENTRY(hyper_ssm_i) mov cr.ipsr=r29;; // set shared_mem ipsr (from ipsr in r30 with ipsr.ri already set) extr.u r29=r30,IA64_PSR_CPL0_BIT,2;; - cmp.eq p6,p7=3,r29;; -(p6) dep r30=-1,r30,IA64_PSR_CPL0_BIT,2 + cmp.eq p7,p0=CONFIG_CPL0_EMUL,r29;; (p7) dep r30=0,r30,IA64_PSR_CPL0_BIT,2 ;; // FOR SSM_I ONLY, also turn on psr.i and psr.ic @@ -441,20 +439,18 @@ GLOBAL_ENTRY(fast_tick_reflect) st8 [r21]=r16 ;; // set cr.ipsr (make sure cpl==2!) mov r29=r17 ;; - movl r28=DELIVER_PSR_SET;; - movl r27=~(DELIVER_PSR_CLR|IA64_PSR_CPL0);; + movl r28=DELIVER_PSR_SET | (CONFIG_CPL0_EMUL << IA64_PSR_CPL0_BIT);; + movl r27=~(DELIVER_PSR_CLR|IA64_PSR_CPL0|IA64_PSR_CPL1);; + and r29=r29,r27;; or r29=r29,r28;; - and r29=r29,r27;; mov cr.ipsr=r29;; // set shared_mem ipsr (from ipsr in r17 with ipsr.ri already set) extr.u r29=r17,IA64_PSR_CPL0_BIT,2;; - cmp.eq p6,p7=3,r29;; -(p6) dep r17=-1,r17,IA64_PSR_CPL0_BIT,2 + cmp.eq p7,p0=CONFIG_CPL0_EMUL,r29;; (p7) dep r17=0,r17,IA64_PSR_CPL0_BIT,2 ;; movl r28=(IA64_PSR_DT|IA64_PSR_IT|IA64_PSR_RT);; movl r27=~(IA64_PSR_BE|IA64_PSR_PP|IA64_PSR_BN|IA64_PSR_I|IA64_PSR_IC);; - dep r21=-1,r21,IA64_PSR_CPL1_BIT,1 ;; or r17=r17,r28;; and r17=r17,r27;; ld4 r16=[r18];; @@ -620,10 +616,10 @@ ENTRY(fast_reflect) movl r21=THIS_CPU(current_psr_i_addr) mov r29=r30 ;; ld8 r21=[r21] - movl r28=DELIVER_PSR_SET;; - movl r27=~(DELIVER_PSR_CLR|IA64_PSR_CPL0);; + movl r28=DELIVER_PSR_SET | (CONFIG_CPL0_EMUL << IA64_PSR_CPL0_BIT);; + movl r27=~(DELIVER_PSR_CLR|IA64_PSR_CPL0|IA64_PSR_CPL1);; + and r29=r29,r27;; or r29=r29,r28;; - and r29=r29,r27;; // set hpsr_dfh to ipsr adds r28=XSI_HPSR_DFH_OFS-XSI_PSR_IC_OFS,r18;; ld1 r28=[r28];; @@ -631,8 +627,7 @@ ENTRY(fast_reflect) mov cr.ipsr=r29;; // set shared_mem ipsr (from ipsr in r30 with ipsr.ri already set) extr.u r29=r30,IA64_PSR_CPL0_BIT,2;; - cmp.eq p6,p7=3,r29;; -(p6) dep r30=-1,r30,IA64_PSR_CPL0_BIT,2 + cmp.eq p7,p0=CONFIG_CPL0_EMUL,r29;; (p7) dep r30=0,r30,IA64_PSR_CPL0_BIT,2 ;; movl r28=(IA64_PSR_DT|IA64_PSR_IT|IA64_PSR_RT);; @@ -1112,14 +1107,17 @@ 1: // OK now, let's do an rfi. just_do_rfi: // r18=&vpsr.i|vpsr.ic, r21==vpsr, r22=vcr.iip - mov cr.iip=r22;; + mov cr.iip=r22 + extr.u r19=r21,IA64_PSR_CPL0_BIT,2 adds r20=XSI_IFS_OFS-XSI_PSR_IC_OFS,r18 ;; + cmp.gtu p7,p0=CONFIG_CPL0_EMUL,r19 ld8 r20=[r20];; +(p7) mov r19=CONFIG_CPL0_EMUL dep r20=0,r20,38,25;; // ensure ifs has no reserved bits set mov cr.ifs=r20 ;; - // ipsr.cpl == (vcr.ipsr.cpl == 0) 2 : 3; + // ipsr.cpl = max(vcr.ipsr.cpl, IA64_PSR_CPL0_BIT); movl r20=THIS_CPU(current_psr_i_addr) - dep r21=-1,r21,IA64_PSR_CPL1_BIT,1 ;; + dep r21=r19,r21,IA64_PSR_CPL0_BIT,2;; // vpsr.i = vcr.ipsr.i; vpsr.ic = vcr.ipsr.ic ld8 r20=[r20] mov r19=1 @@ -1287,12 +1285,12 @@ ENTRY(rfi_with_interrupt) movl r22=THIS_CPU(current_psr_i_addr) // set cr.ipsr (make sure cpl==2!) mov r29=r17 - movl r28=DELIVER_PSR_SET;; + movl r27=~(DELIVER_PSR_CLR|IA64_PSR_CPL0|IA64_PSR_CPL1) + movl r28=DELIVER_PSR_SET | (CONFIG_CPL0_EMUL << IA64_PSR_CPL0_BIT);; mov r20=1;; ld8 r22=[r22] - movl r27=~(DELIVER_PSR_CLR|IA64_PSR_CPL0) + and r29=r29,r27;; or r29=r29,r28;; - and r29=r29,r27;; mov cr.ipsr=r29;; // v.ipsr and v.iip are already set (and v.iip validated) as rfi target // set shared_mem interrupt_delivery_enabled to 0 @@ -1935,7 +1933,7 @@ ENTRY(fast_insert) or r20=r20,r21 ;; // r20==return value from lookup_domain_mpa // r16=pteval,r20=pteval2 movl r19=_PAGE_PPN_MASK - movl r21=_PAGE_PL_2;; + movl r21=_PAGE_PL_PRIV;; andcm r25=r16,r19;; // r25==pteval & ~_PAGE_PPN_MASK and r22=r20,r19;; or r22=r22,r21;; diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/xen/ivt.S --- a/xen/arch/ia64/xen/ivt.S Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/xen/ivt.S Tue Jul 17 10:20:21 2007 +0100 @@ -154,14 +154,17 @@ late_alt_itlb_miss: movl r17=PAGE_KERNEL movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff) ;; + mov r20=cr.itir extr.u r23=r21,IA64_PSR_CPL0_BIT,2 // extract psr.cpl and r19=r19,r16 // clear ed, reserved bits, and PTE ctrl bits extr.u r18=r16,XEN_VIRT_UC_BIT,1 // extract UC bit ;; cmp.ne p8,p0=r0,r23 // psr.cpl != 0? or r19=r17,r19 // insert PTE control bits into r19 + dep r20=0,r20,IA64_ITIR_KEY,IA64_ITIR_KEY_LEN // clear the key ;; dep r19=r18,r19,4,1 // set bit 4 (uncached) if access to UC area. + mov cr.itir=r20 // set itir with cleared key (p8) br.cond.spnt page_fault ;; itc.i r19 // insert the TLB entry @@ -195,6 +198,7 @@ late_alt_dtlb_miss: (p9) cmp.eq.or.andcm p6,p7=IA64_ISR_CODE_LFETCH,r22 // check isr.code field (p8) br.cond.spnt page_fault ;; + mov r20=cr.itir #ifdef CONFIG_VIRTUAL_FRAME_TABLE shr r22=r16,56 // Test for the address of virtual frame_table ;; @@ -204,11 +208,13 @@ late_alt_dtlb_miss: // If it is not a Xen address, handle it via page_fault. extr.u r22=r16,59,5 ;; + dep r20=0,r20,IA64_ITIR_KEY,IA64_ITIR_KEY_LEN // clear the key cmp.ne p8,p0=0x1e,r22 (p8) br.cond.sptk page_fault ;; dep r21=-1,r21,IA64_PSR_ED_BIT,1 or r19=r19,r17 // insert PTE control bits into r19 + mov cr.itir=r20 // set itir with cleared key ;; dep r19=r18,r19,4,1 // set bit 4 (uncached) if access to UC area (p6) mov cr.ipsr=r21 @@ -242,7 +248,7 @@ GLOBAL_ENTRY(frametable_miss) shladd r24=r19,3,r24 // r24=&pte[pte_offset(addr)] ;; (p7) ld8 r24=[r24] // r24=pte[pte_offset(addr)] - mov r25=0x700|(PAGE_SHIFT<<2) // key=7 + mov r25=(PAGE_SHIFT<<IA64_ITIR_PS) (p6) br.spnt.few frametable_fault ;; mov cr.itir=r25 @@ -370,16 +376,6 @@ ENTRY(dkey_miss) DBG_FAULT(7) FAULT_OR_REFLECT(7) END(dkey_miss) - - -#define SAVE_MIN_COVER_DONE DO_SAVE_MIN(,mov r30=cr.ifs,) - -// same as dispatch_break_fault except cover has already been done -GLOBAL_ENTRY(dispatch_slow_hyperprivop) - SAVE_MIN_COVER_DONE - ;; - br.sptk.many dispatch_break_fault_post_save -END(dispatch_slow_hyperprivop) .org ia64_ivt+0x2000 ////////////////////////////////////////////////////////////////////////// @@ -510,7 +506,8 @@ ENTRY(break_fault) (p7) br.spnt.many dispatch_privop_fault ;; #endif - // if (ipsr.cpl == 2 && (iim - HYPERPRIVOP_START) < HYPERPRIVOP_MAX) + // if (ipsr.cpl == CONFIG_CPL0_EMUL && + // (iim - HYPERPRIVOP_START) < HYPERPRIVOP_MAX) // this is a hyperprivop. A hyperprivop is hand-coded assembly with // psr.ic off which means it can make no calls, cannot use r1-r15, // and it can have no memory accesses unless they are to pinned @@ -524,7 +521,7 @@ ENTRY(break_fault) ;; cmp.gtu p7,p0=r21,r20 ;; - cmp.eq.and p7,p0=2,r19 // ipsr.cpl==2 + cmp.eq.and p7,p0=CONFIG_CPL0_EMUL,r19 // ipsr.cpl==CONFIG_CPL0_EMUL (p7) br.sptk.many fast_hyperprivop ;; movl r22=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET @@ -535,7 +532,7 @@ ENTRY(break_fault) ;; ld4 r23=[r23];; cmp4.eq p6,p0=r23,r17;; // Xen-reserved breakimm? - cmp.eq.and p6,p0=2,r19 + cmp.eq.and p6,p0=CONFIG_CPL0_EMUL,r19 (p6) br.spnt.many fast_hypercall ;; br.sptk.many fast_break_reflect @@ -736,7 +733,6 @@ ENTRY(interrupt) ENTRY(interrupt) DBG_FAULT(12) mov r31=pr // prepare to save predicates - ;; mov r30=cr.ivr // pass cr.ivr as first arg // FIXME: this is a hack... use cpuinfo.ksoftirqd because its // not used anywhere else and we need a place to stash ivr and @@ -744,7 +740,6 @@ ENTRY(interrupt) movl r29=THIS_CPU(cpu_info)+IA64_CPUINFO_KSOFTIRQD_OFFSET ;; st8 [r29]=r30 - ;; movl r28=slow_interrupt ;; mov r29=rp @@ -805,7 +800,6 @@ dispatch_break_fault_post_save: movl r14=ia64_leave_kernel ;; mov rp=r14 -// br.sptk.many ia64_prepare_handle_break // TODO: why commented out? br.call.sptk.many b6=ia64_handle_break END(dispatch_break_fault) @@ -997,7 +991,6 @@ ENTRY(dispatch_privop_fault) movl r14=ia64_leave_kernel ;; mov rp=r14 -// br.sptk.many ia64_prepare_handle_privop // TODO: why commented out? br.call.sptk.many b6=ia64_handle_privop END(dispatch_privop_fault) @@ -1094,11 +1087,10 @@ ENTRY(daccess_rights) ENTRY(daccess_rights) DBG_FAULT(23) mov r31=pr - ;; mov r16=cr.isr mov r17=cr.ifa mov r19=23 - movl r20=0x5300 + mov r20=0x5300 br.sptk.many fast_access_reflect ;; END(daccess_rights) @@ -1115,9 +1107,6 @@ ENTRY(general_exception) (p6) br.sptk.many dispatch_privop_fault ;; FAULT_OR_REFLECT(24) - ;; - mov r19=24 // fault number - br.sptk.many dispatch_to_fault_handler END(general_exception) .org ia64_ivt+0x5500 @@ -1125,34 +1114,7 @@ END(general_exception) // 0x5500 Entry 25 (size 16 bundles) Disabled FP-Register (35) ENTRY(disabled_fp_reg) DBG_FAULT(25) -#if 0 // TODO: can this be removed? - mov r20=pr - movl r16=0x2000000000000000 - movl r17=0x2000000000176b60 - mov r18=cr.iip - mov r19=rr[r16] - movl r22=0xe95d0439 - ;; - mov pr=r0,-1 - ;; - cmp.eq p6,p7=r22,r19 - ;; - (p6) cmp.eq p8,p9=r17,r18 - (p8) br.sptk.few floating_panic - ;; - mov pr=r20,-1 - ;; -#endif FAULT_OR_REFLECT(25) -//floating_panic: // TODO: can this be removed? -// br.sptk.many floating_panic - ;; - rsm psr.dfh // ensure we can access fph - ;; - srlz.d - mov r31=pr - mov r19=25 - br.sptk.many dispatch_to_fault_handler END(disabled_fp_reg) .org ia64_ivt+0x5600 @@ -1183,11 +1145,7 @@ END(speculation_vector) // 0x5900 Entry 29 (size 16 bundles) Debug (16,28,56) ENTRY(debug_vector) DBG_FAULT(29) -#ifdef XEN FAULT_OR_REFLECT(29) -#else - FAULT(29) -#endif END(debug_vector) .org ia64_ivt+0x5a00 diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/xen/mm.c --- a/xen/arch/ia64/xen/mm.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/xen/mm.c Tue Jul 17 10:20:21 2007 +0100 @@ -546,7 +546,7 @@ u64 translate_domain_pte(u64 pteval, u64 /* Ignore non-addr bits of pteval2 and force PL0->2 (PL3 is unaffected) */ return (pteval & ~_PAGE_PPN_MASK) | - (pteval2 & _PAGE_PPN_MASK) | _PAGE_PL_2; + (pteval2 & _PAGE_PPN_MASK) | _PAGE_PL_PRIV; } // given a current domain metaphysical address, return the physical address @@ -711,7 +711,8 @@ unsigned long lookup_domain_mpa(struct d p2m_entry_set(entry, NULL, __pte(0)); //XXX This is a work around until the emulation memory access to a region // where memory or device are attached is implemented. - return pte_val(pfn_pte(0, __pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX))); + return pte_val(pfn_pte(0, __pgprot(__DIRTY_BITS | _PAGE_PL_PRIV | + _PAGE_AR_RWX))); } // FIXME: ONLY USE FOR DOMAIN PAGE_SIZE == PAGE_SIZE @@ -785,7 +786,7 @@ __assign_new_domain_page(struct domain * set_pte_rel(pte, pfn_pte(maddr >> PAGE_SHIFT, __pgprot(_PAGE_PGC_ALLOCATED | __DIRTY_BITS | - _PAGE_PL_2 | _PAGE_AR_RWX))); + _PAGE_PL_PRIV | _PAGE_AR_RWX))); smp_mb(); return p; @@ -820,7 +821,7 @@ static unsigned long static unsigned long flags_to_prot (unsigned long flags) { - unsigned long res = _PAGE_PL_2 | __DIRTY_BITS; + unsigned long res = _PAGE_PL_PRIV | __DIRTY_BITS; res |= flags & ASSIGN_readonly ? _PAGE_AR_R: _PAGE_AR_RWX; res |= flags & ASSIGN_nocache ? _PAGE_MA_UC: _PAGE_MA_WB; @@ -2020,20 +2021,6 @@ static int alloc_page_type(struct page_i return 1; } -unsigned long __get_free_pages(unsigned int mask, unsigned int order) -{ - void *p = alloc_xenheap_pages(order); - - memset(p,0,PAGE_SIZE<<order); - return (unsigned long)p; -} - -void __free_pages(struct page_info *page, unsigned int order) -{ - if (order) BUG(); - free_xenheap_page(page); -} - static int opt_p2m_xenheap; boolean_param("p2m_xenheap", opt_p2m_xenheap); diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/xen/oprofile/perfmon.c --- a/xen/arch/ia64/xen/oprofile/perfmon.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/xen/oprofile/perfmon.c Tue Jul 17 10:20:21 2007 +0100 @@ -119,19 +119,10 @@ __exitcall(xenoprof_perfmon_exit); /////////////////////////////////////////////////////////////////////////// // glue methods for xenoprof and perfmon. int -xenoprof_arch_init(int *num_events, int *is_primary, char *cpu_type) +xenoprof_arch_init(int *num_events, char *cpu_type) { *num_events = 0; strlcpy(cpu_type, get_cpu_type(), XENOPROF_CPU_TYPE_SIZE); - - *is_primary = 0; - if (xenoprof_primary_profiler == NULL) { - /* For now, only dom0 can be the primary profiler */ - if (current->domain->domain_id == 0) { - *is_primary = 1; - } - } else if (xenoprof_primary_profiler == current->domain) - *is_primary = 1; return 0; } diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/xen/oprofile/xenoprof.c --- a/xen/arch/ia64/xen/oprofile/xenoprof.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/xen/oprofile/xenoprof.c Tue Jul 17 10:20:21 2007 +0100 @@ -28,20 +28,26 @@ int int xenoprofile_get_mode(struct vcpu *v, struct cpu_user_regs * const regs) { - int mode = 0; + int mode; // mode // 0: user, 1: kernel, 2: xen - // Xen/IA64 uses ring2 for kernel, and doesn't use ring1. - if (ring_2(regs)) - mode = 1; - else if (ring_0(regs)) - mode = 2; - else if (ring_1(regs)) { - gdprintk(XENLOG_ERR, "%s:%d ring1 is used!\n", __func__, __LINE__); - mode = 1;// fall back to kernel mode. + switch (ring(regs)) + { + case 3: + mode = 0; + break; + case CONFIG_CPL0_EMUL: + mode = 1; + break; + case 0: + mode = 2; + break; + default: + gdprintk(XENLOG_ERR, "%s:%d ring%d is used!\n", __func__, + __LINE__, 3 - CONFIG_CPL0_EMUL); + mode = 1; /* fall back to kernel mode. */ } - return mode; } diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/xen/privop.c --- a/xen/arch/ia64/xen/privop.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/xen/privop.c Tue Jul 17 10:20:21 2007 +0100 @@ -636,7 +636,7 @@ static IA64FAULT priv_handle_op(VCPU * v } if (slot_type == B && inst.generic.major == 0 && inst.B8.x6 == 0x0) { // break instr for privified cover - } else if (privlvl != 2) + } else if (privlvl > CONFIG_CPL0_EMUL) return IA64_ILLOP_FAULT; switch (slot_type) { case M: diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/xen/vcpu.c --- a/xen/arch/ia64/xen/vcpu.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/xen/vcpu.c Tue Jul 17 10:20:21 2007 +0100 @@ -158,7 +158,7 @@ void vcpu_init_regs(struct vcpu *v) regs->cr_ipsr &= ~(IA64_PSR_BITS_TO_CLEAR | IA64_PSR_RI | IA64_PSR_IS); // domain runs at PL2 - regs->cr_ipsr |= 2UL << IA64_PSR_CPL0_BIT; + regs->cr_ipsr = vcpu_pl_adjust(regs->cr_ipsr,IA64_PSR_CPL0_BIT); // lazy fp PSCB(v, hpsr_dfh) = 1; PSCB(v, hpsr_mfh) = 0; @@ -174,7 +174,7 @@ void vcpu_init_regs(struct vcpu *v) VCPU(v, dcr) = 0; } else { init_all_rr(v); - regs->ar_rsc |= (2 << 2); /* force PL2/3 */ + regs->ar_rsc = vcpu_pl_adjust(regs->ar_rsc, 2); VCPU(v, banknum) = 1; VCPU(v, metaphysical_mode) = 1; VCPU(v, interrupt_mask_addr) = @@ -496,7 +496,7 @@ IA64FAULT vcpu_set_psr(VCPU * vcpu, u64 PSCB(vcpu, interrupt_collection_enabled) = vpsr.ic; vcpu_set_metaphysical_mode(vcpu, !(vpsr.dt && vpsr.rt && vpsr.it)); - newpsr.cpl |= vpsr.cpl | 2; + newpsr.cpl |= max_t(u64, vpsr.cpl, CONFIG_CPL0_EMUL); if (PSCB(vcpu, banknum) != vpsr.bn) { if (vpsr.bn) @@ -535,10 +535,10 @@ u64 vcpu_get_psr(VCPU * vcpu) newpsr.ia64_psr.pp = PSCB(vcpu, vpsr_pp); /* Fool cpl. */ - if (ipsr.ia64_psr.cpl < 3) + if (ipsr.ia64_psr.cpl <= CONFIG_CPL0_EMUL) newpsr.ia64_psr.cpl = 0; else - newpsr.ia64_psr.cpl = 3; + newpsr.ia64_psr.cpl = ipsr.ia64_psr.cpl; newpsr.ia64_psr.bn = PSCB(vcpu, banknum); @@ -1646,7 +1646,7 @@ IA64FAULT vcpu_translate(VCPU * vcpu, u6 } else { *pteval = (address & _PAGE_PPN_MASK) | - __DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX; + __DIRTY_BITS | _PAGE_PL_PRIV | _PAGE_AR_RWX; *itir = PAGE_SHIFT << 2; perfc_incr(phys_translate); return IA64_NO_FAULT; @@ -1709,11 +1709,13 @@ IA64FAULT vcpu_translate(VCPU * vcpu, u6 vcpu_thash(vcpu, address, iha); if (!(rr & RR_VE_MASK) || !(pta & IA64_PTA_VE)) { REGS *regs = vcpu_regs(vcpu); - // NOTE: This is specific code for linux kernel - // We assume region 7 is identity mapped - if (region == 7 && ia64_psr(regs)->cpl == 2) { + struct opt_feature* optf = &(vcpu->domain->arch.opt_feature); + + /* Optimization for identity mapped region 7 OS (linux) */ + if (optf->mask & XEN_IA64_OPTF_IDENT_MAP_REG7 && + region == 7 && ia64_psr(regs)->cpl == CONFIG_CPL0_EMUL) { pte.val = address & _PAGE_PPN_MASK; - pte.val = pte.val | pgprot_val(PAGE_KERNEL); + pte.val = pte.val | optf->im_reg7.pgprot; goto out; } return is_data ? IA64_ALT_DATA_TLB_VECTOR : @@ -1773,33 +1775,65 @@ IA64FAULT vcpu_tak(VCPU * vcpu, u64 vadr IA64FAULT vcpu_set_dbr(VCPU * vcpu, u64 reg, u64 val) { - // TODO: unimplemented DBRs return a reserved register fault - // TODO: Should set Logical CPU state, not just physical - ia64_set_dbr(reg, val); + if (reg >= IA64_NUM_DBG_REGS) + return IA64_RSVDREG_FAULT; + if ((reg & 1) == 0) { + /* Validate address. */ + if (val >= HYPERVISOR_VIRT_START && val <= HYPERVISOR_VIRT_END) + return IA64_ILLOP_FAULT; + } else { + if (!VMX_DOMAIN(vcpu)) { + /* Mask PL0. */ + val &= ~(1UL << 56); + } + } + if (val != 0) + vcpu->arch.dbg_used |= (1 << reg); + else + vcpu->arch.dbg_used &= ~(1 << reg); + vcpu->arch.dbr[reg] = val; + if (vcpu == current) + ia64_set_dbr(reg, val); return IA64_NO_FAULT; } IA64FAULT vcpu_set_ibr(VCPU * vcpu, u64 reg, u64 val) { - // TODO: unimplemented IBRs return a reserved register fault - // TODO: Should set Logical CPU state, not just physical - ia64_set_ibr(reg, val); + if (reg >= IA64_NUM_DBG_REGS) + return IA64_RSVDREG_FAULT; + if ((reg & 1) == 0) { + /* Validate address. */ + if (val >= HYPERVISOR_VIRT_START && val <= HYPERVISOR_VIRT_END) + return IA64_ILLOP_FAULT; + } else { + if (!VMX_DOMAIN(vcpu)) { + /* Mask PL0. */ + val &= ~(1UL << 56); + } + } + if (val != 0) + vcpu->arch.dbg_used |= (1 << (reg + IA64_NUM_DBG_REGS)); + else + vcpu->arch.dbg_used &= ~(1 << (reg + IA64_NUM_DBG_REGS)); + vcpu->arch.ibr[reg] = val; + if (vcpu == current) + ia64_set_ibr(reg, val); return IA64_NO_FAULT; } IA64FAULT vcpu_get_dbr(VCPU * vcpu, u64 reg, u64 * pval) { - // TODO: unimplemented DBRs return a reserved register fault - u64 val = ia64_get_dbr(reg); - *pval = val; + if (reg >= IA64_NUM_DBG_REGS) + return IA64_RSVDREG_FAULT; + *pval = vcpu->arch.dbr[reg]; return IA64_NO_FAULT; } IA64FAULT vcpu_get_ibr(VCPU * vcpu, u64 reg, u64 * pval) { - // TODO: unimplemented IBRs return a reserved register fault - u64 val = ia64_get_ibr(reg); - *pval = val; + if (reg >= IA64_NUM_DBG_REGS) + return IA64_RSVDREG_FAULT; + *pval = vcpu->arch.ibr[reg]; return IA64_NO_FAULT; } @@ -2002,8 +2036,8 @@ IA64FAULT vcpu_set_rr(VCPU * vcpu, u64 r IA64FAULT vcpu_set_rr(VCPU * vcpu, u64 reg, u64 val) { PSCB(vcpu, rrs)[reg >> 61] = val; - // warning: set_one_rr() does it "live" - set_one_rr(reg, val); + if (vcpu == current) + set_one_rr(reg, val); return IA64_NO_FAULT; } @@ -2062,8 +2096,8 @@ vcpu_set_tr_entry_rid(TR_ENTRY * trp, u6 trp->rid = rid; ps = trp->ps; new_pte.val = pte; - if (new_pte.pl < 2) - new_pte.pl = 2; + if (new_pte.pl < CONFIG_CPL0_EMUL) + new_pte.pl = CONFIG_CPL0_EMUL; trp->vadr = ifa & ~0xfff; if (ps > 12) { // "ignore" relevant low-order bits new_pte.ppn &= ~((1UL << (ps - 12)) - 1); diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/xen/vhpt.c --- a/xen/arch/ia64/xen/vhpt.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/xen/vhpt.c Tue Jul 17 10:20:21 2007 +0100 @@ -20,8 +20,6 @@ #include <asm/vcpu.h> #include <asm/vcpumask.h> #include <asm/vmmu.h> - -extern long running_on_sim; DEFINE_PER_CPU (unsigned long, vhpt_paddr); DEFINE_PER_CPU (unsigned long, vhpt_pend); diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/xen/xenasm.S --- a/xen/arch/ia64/xen/xenasm.S Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/xen/xenasm.S Tue Jul 17 10:20:21 2007 +0100 @@ -11,6 +11,7 @@ #include <asm/pgtable.h> #include <asm/vhpt.h> #include <asm/asm-xsi-offsets.h> +#include <asm/vmmu.h> #include <public/xen.h> // Change rr7 to the passed value while ensuring @@ -148,7 +149,7 @@ 1: // Shared info mov r24=XSI_SHIFT<<2 - movl r25=__pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RW) + movl r25=__pgprot(__DIRTY_BITS | _PAGE_PL_PRIV | _PAGE_AR_RW) ;; ptr.d in3,r24 or r23=in1,r25 // construct PA | page properties diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/xen/xenmisc.c --- a/xen/arch/ia64/xen/xenmisc.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/xen/xenmisc.c Tue Jul 17 10:20:21 2007 +0100 @@ -33,25 +33,6 @@ void hpsim_setup(char **x) #ifdef CONFIG_SMP init_smp_config(); #endif -} - -// called from mem_init... don't think s/w I/O tlb is needed in Xen -//void swiotlb_init(void) { } ...looks like it IS needed - -long -is_platform_hp_ski(void) -{ - int i; - long cpuid[6]; - - for (i = 0; i < 5; ++i) - cpuid[i] = ia64_get_cpuid(i); - if ((cpuid[0] & 0xff) != 'H') return 0; - if ((cpuid[3] & 0xff) != 0x4) return 0; - if (((cpuid[3] >> 8) & 0xff) != 0x0) return 0; - if (((cpuid[3] >> 16) & 0xff) != 0x0) return 0; - if (((cpuid[3] >> 24) & 0x7) != 0x7) return 0; - return 1; } struct pt_regs *guest_cpu_user_regs(void) { return vcpu_regs(current); } diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/xen/xenpatch.c --- a/xen/arch/ia64/xen/xenpatch.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/xen/xenpatch.c Tue Jul 17 10:20:21 2007 +0100 @@ -90,25 +90,26 @@ ia64_patch_imm64 (u64 insn_addr, u64 val ia64_patch(insn_addr + 1, 0x1ffffffffffUL, val >> 22); } -extern char frametable_miss; -extern unsigned long xen_pstart; - /* * Add more patch points in seperate functions as appropriate */ static void __init xen_patch_frametable_miss(u64 offset) { +#ifdef CONFIG_VIRTUAL_FRAME_TABLE + extern char frametable_miss; u64 addr, val; addr = (u64)&frametable_miss; val = get_imm64(addr) + offset; ia64_patch_imm64(addr, val); +#endif } void __init xen_patch_kernel(void) { + extern unsigned long xen_pstart; unsigned long patch_offset; patch_offset = xen_pstart - (KERNEL_START - PAGE_OFFSET); diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/xen/xensetup.c --- a/xen/arch/ia64/xen/xensetup.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/xen/xensetup.c Tue Jul 17 10:20:21 2007 +0100 @@ -7,7 +7,6 @@ #include <xen/config.h> #include <xen/lib.h> #include <xen/errno.h> -//#include <xen/spinlock.h> #include <xen/multiboot.h> #include <xen/sched.h> #include <xen/mm.h> @@ -43,7 +42,6 @@ int find_max_pfn (unsigned long, unsigne int find_max_pfn (unsigned long, unsigned long, void *); /* FIXME: which header these declarations should be there ? */ -extern long is_platform_hp_ski(void); extern void early_setup_arch(char **); extern void late_setup_arch(char **); extern void hpsim_serial_init(void); @@ -84,7 +82,6 @@ boolean_param("xencons_poll", opt_xencon */ unsigned int opt_xenheap_megabytes = XENHEAP_DEFAULT_MB; unsigned long xenheap_size = XENHEAP_DEFAULT_SIZE; -extern long running_on_sim; unsigned long xen_pstart; void *xen_pickle_offset __read_mostly; @@ -255,6 +252,31 @@ static void noinline init_done(void) startup_cpu_idle_loop(); } +int running_on_sim; + +static int __init +is_platform_hp_ski(void) +{ + int i; + long cpuid[6]; + + for (i = 0; i < 5; ++i) + cpuid[i] = ia64_get_cpuid(i); + + if ((cpuid[0] & 0xff) != 'H') + return 0; + if ((cpuid[3] & 0xff) != 0x4) + return 0; + if (((cpuid[3] >> 8) & 0xff) != 0x0) + return 0; + if (((cpuid[3] >> 16) & 0xff) != 0x0) + return 0; + if (((cpuid[3] >> 24) & 0x7) != 0x7) + return 0; + + return 1; +} + void __init start_kernel(void) { char *cmdline; @@ -273,9 +295,10 @@ void __init start_kernel(void) /* Be sure the struct shared_info size is <= XSI_SIZE. */ BUILD_BUG_ON(sizeof(struct shared_info) > XSI_SIZE); - running_on_sim = is_platform_hp_ski(); /* Kernel may be relocated by EFI loader */ xen_pstart = ia64_tpa(KERNEL_START); + + running_on_sim = is_platform_hp_ski(); early_setup_arch(&cmdline); diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/ia64/xen/xentime.c --- a/xen/arch/ia64/xen/xentime.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/ia64/xen/xentime.c Tue Jul 17 10:20:21 2007 +0100 @@ -126,9 +126,7 @@ xen_timer_interrupt (int irq, void *dev_ new_itm = local_cpu_data->itm_next; - while (time_after(ia64_get_itc(), new_itm)) { - new_itm += local_cpu_data->itm_delta; - + while (1) { if (smp_processor_id() == TIME_KEEPER_ID) { /* * Here we are in the timer irq handler. We have irqs locally @@ -150,6 +148,10 @@ xen_timer_interrupt (int irq, void *dev_ local_cpu_data->itm_next = new_itm; + if (time_after(new_itm, ia64_get_itc())) + break; + + new_itm += local_cpu_data->itm_delta; } if (!is_idle_domain(current->domain) && !VMX_DOMAIN(current)) { diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/x86/acpi/Makefile --- a/xen/arch/x86/acpi/Makefile Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/x86/acpi/Makefile Tue Jul 17 10:20:21 2007 +0100 @@ -1,1 +1,2 @@ obj-y += boot.o obj-y += boot.o +obj-y += power.o suspend.o wakeup_prot.o diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/x86/acpi/power.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/arch/x86/acpi/power.c Tue Jul 17 10:20:21 2007 +0100 @@ -0,0 +1,274 @@ +/* drivers/acpi/sleep/power.c - PM core functionality for Xen + * + * Copyrights from Linux side: + * Copyright (c) 2000-2003 Patrick Mochel + * Copyright (C) 2001-2003 Pavel Machek <pavel@xxxxxxx> + * Copyright (c) 2003 Open Source Development Lab + * Copyright (c) 2004 David Shaohua Li <shaohua.li@xxxxxxxxx> + * Copyright (c) 2005 Alexey Starikovskiy <alexey.y.starikovskiy@xxxxxxxxx> + * + * Slimmed with Xen specific support. + */ + +#include <xen/config.h> +#include <asm/io.h> +#include <asm/acpi.h> +#include <xen/acpi.h> +#include <xen/errno.h> +#include <xen/iocap.h> +#include <xen/sched.h> +#include <asm/acpi.h> +#include <asm/irq.h> +#include <asm/init.h> +#include <xen/spinlock.h> +#include <xen/sched.h> +#include <xen/domain.h> +#include <xen/console.h> +#include <public/platform.h> + +#define pmprintk(_l, _f, _a...) printk(_l "<PM>" _f, ## _a ) + +u8 sleep_states[ACPI_S_STATE_COUNT]; +DEFINE_SPINLOCK(pm_lock); + +struct acpi_sleep_info { + uint16_t pm1a_cnt; + uint16_t pm1b_cnt; + uint16_t pm1a_evt; + uint16_t pm1b_evt; + uint16_t pm1a_cnt_val; + uint16_t pm1b_cnt_val; + uint32_t sleep_state; +} acpi_sinfo; + +extern void do_suspend_lowlevel(void); + +static char *acpi_states[ACPI_S_STATE_COUNT] = +{ + [ACPI_STATE_S1] = "standby", + [ACPI_STATE_S3] = "mem", + [ACPI_STATE_S4] = "disk", +}; + +unsigned long acpi_video_flags; +unsigned long saved_videomode; + +/* XXX: Add suspend failure recover later */ +static int device_power_down(void) +{ + console_suspend(); + + time_suspend(); + + i8259A_suspend(); + + ioapic_suspend(); + + lapic_suspend(); + + return 0; +} + +static void device_power_up(void) +{ + lapic_resume(); + + ioapic_resume(); + + i8259A_resume(); + + time_resume(); + + console_resume(); +} + +static void freeze_domains(void) +{ + struct domain *d; + + for_each_domain(d) + if (d->domain_id != 0) + domain_pause(d); +} + +static void thaw_domains(void) +{ + struct domain *d; + + for_each_domain(d) + if (d->domain_id != 0) + domain_unpause(d); +} + +/* Main interface to do xen specific suspend/resume */ +int enter_state(u32 state) +{ + unsigned long flags; + int error; + + if (state <= ACPI_STATE_S0 || state > ACPI_S_STATES_MAX) + return -EINVAL; + + /* Sync lazy state on ths cpu */ + __sync_lazy_execstate(); + pmprintk(XENLOG_INFO, "Flush lazy state\n"); + + if (!spin_trylock(&pm_lock)) + return -EBUSY; + + freeze_domains(); + + hvm_cpu_down(); + + pmprintk(XENLOG_INFO, "PM: Preparing system for %s sleep\n", + acpi_states[state]); + + local_irq_save(flags); + + if ((error = device_power_down())) + { + printk(XENLOG_ERR "Some devices failed to power down\n"); + goto Done; + } + + ACPI_FLUSH_CPU_CACHE(); + + switch (state) + { + case ACPI_STATE_S3: + do_suspend_lowlevel(); + break; + default: + error = -EINVAL; + break; + } + + pmprintk(XENLOG_INFO, "Back to C!\n"); + + device_power_up(); + + pmprintk(XENLOG_INFO, "PM: Finishing wakeup.\n"); + + Done: + local_irq_restore(flags); + + if ( !hvm_cpu_up() ) + BUG(); + + thaw_domains(); + spin_unlock(&pm_lock); + return error; +} + +/* + * Xen just requires address of pm1x_cnt, and ACPI interpreter + * is still kept in dom0. Address of xen wakeup stub will be + * returned, and then dom0 writes that address to FACS. + */ +int set_acpi_sleep_info(struct xenpf_set_acpi_sleep *info) +{ + if (acpi_sinfo.pm1a_cnt) + pmprintk(XENLOG_WARNING, "Multiple setting on acpi sleep info\n"); + + acpi_sinfo.pm1a_cnt = info->pm1a_cnt_port; + acpi_sinfo.pm1b_cnt = info->pm1b_cnt_port; + acpi_sinfo.pm1a_evt = info->pm1a_evt_port; + acpi_sinfo.pm1b_evt = info->pm1b_evt_port; + info->xen_waking_vec = (uint64_t)bootsym_phys(wakeup_start); + + pmprintk(XENLOG_INFO, "pm1a[%x],pm1b[%x],pm1a_e[%x],pm1b_e[%x]" + "wake[%"PRIx64"]", + acpi_sinfo.pm1a_cnt, acpi_sinfo.pm1b_cnt, + acpi_sinfo.pm1a_evt, acpi_sinfo.pm1b_evt, + info->xen_waking_vec); + return 0; +} + +/* + * Dom0 issues this hypercall in place of writing pm1a_cnt. Xen then + * takes over the control and put the system into sleep state really. + * Also video flags and mode are passed here, in case user may use + * "acpi_sleep=***" for video resume. + * + * Guest may issue a two-phases write to PM1x_CNT, to work + * around poorly implemented hardware. It's better to keep + * this logic here. Two writes can be differentiated by + * enable bit setting. + */ +int acpi_enter_sleep(struct xenpf_enter_acpi_sleep *sleep) +{ + if (!IS_PRIV(current->domain) || !acpi_sinfo.pm1a_cnt) + return -EPERM; + + /* Sanity check */ + if (acpi_sinfo.pm1b_cnt_val && + ((sleep->pm1a_cnt_val ^ sleep->pm1b_cnt_val) & + ACPI_BITMASK_SLEEP_ENABLE)) + { + pmprintk(XENLOG_ERR, "Mismatched pm1a/pm1b setting\n"); + return -EINVAL; + } + + /* Write #1 */ + if (!(sleep->pm1a_cnt_val & ACPI_BITMASK_SLEEP_ENABLE)) + { + outw((u16)sleep->pm1a_cnt_val, acpi_sinfo.pm1a_cnt); + if (acpi_sinfo.pm1b_cnt) + outw((u16)sleep->pm1b_cnt_val, acpi_sinfo.pm1b_cnt); + return 0; + } + + /* Write #2 */ + acpi_sinfo.pm1a_cnt_val = sleep->pm1a_cnt_val; + acpi_sinfo.pm1b_cnt_val = sleep->pm1b_cnt_val; + acpi_sinfo.sleep_state = sleep->sleep_state; + acpi_video_flags = sleep->video_flags; + saved_videomode = sleep->video_mode; + + return enter_state(acpi_sinfo.sleep_state); +} + +static int acpi_get_wake_status(void) +{ + uint16_t val; + + /* Wake status is the 15th bit of PM1 status register. (ACPI spec 3.0) */ + val = inw(acpi_sinfo.pm1a_evt) | inw(acpi_sinfo.pm1b_evt); + val &= ACPI_BITMASK_WAKE_STATUS; + val >>= ACPI_BITPOSITION_WAKE_STATUS; + return val; +} + +/* System is really put into sleep state by this stub */ +acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) +{ + ACPI_FLUSH_CPU_CACHE(); + + outw((u16)acpi_sinfo.pm1a_cnt_val, acpi_sinfo.pm1a_cnt); + if (acpi_sinfo.pm1b_cnt) + outw((u16)acpi_sinfo.pm1b_cnt_val, acpi_sinfo.pm1b_cnt); + + /* Wait until we enter sleep state, and spin until we wake */ + while (!acpi_get_wake_status()); + return_ACPI_STATUS(AE_OK); +} + +static int __init acpi_sleep_init(void) +{ + int i = 0; + + pmprintk(XENLOG_INFO, "ACPI (supports"); + for (i = 0; i < ACPI_S_STATE_COUNT; i++) + { + if (i == ACPI_STATE_S3) + { + sleep_states[i] = 1; + printk(" S%d", i); + } + else + sleep_states[i] = 0; + } + printk(")\n"); + return 0; +} +__initcall(acpi_sleep_init); diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/x86/acpi/suspend.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/arch/x86/acpi/suspend.c Tue Jul 17 10:20:21 2007 +0100 @@ -0,0 +1,85 @@ +/* + * Suspend support specific for i386. + * + * Distribute under GPLv2 + * + * Copyright (c) 2002 Pavel Machek <pavel@xxxxxxx> + * Copyright (c) 2001 Patrick Mochel <mochel@xxxxxxxx> + */ +#include <xen/config.h> +#include <xen/acpi.h> +#include <xen/smp.h> +#include <asm/processor.h> +#include <asm/msr.h> +#include <asm/flushtlb.h> +#include <asm/hvm/hvm.h> +#include <asm/hvm/support.h> +#include <asm/i387.h> + +/* Following context save/restore happens on the real context + * of current vcpu, with a lazy state sync forced earlier. + */ +#if defined(CONFIG_X86_64) +unsigned long saved_lstar, saved_cstar; +#endif +void save_rest_processor_state(void) +{ + /* + * Net effect of unlazy_fpu is to set cr0.ts and thus there's no + * need to restore fpu after resume. + */ + if (!is_idle_vcpu(current)) + unlazy_fpu(current); + +#if defined(CONFIG_X86_64) + rdmsrl(MSR_CSTAR, saved_cstar); + rdmsrl(MSR_LSTAR, saved_lstar); +#endif + + bootsym(video_flags) = acpi_video_flags; + bootsym(video_mode) = saved_videomode; +} + +#define loaddebug(_v,_reg) \ + __asm__ __volatile__ ("mov %0,%%db" #_reg : : "r" ((_v)->debugreg[_reg])) + +void restore_rest_processor_state(void) +{ + int cpu = smp_processor_id(); + struct tss_struct *t = &init_tss[cpu]; + struct vcpu *v = current; + + /* Really scared by suffixed comment from Linux, and keep it for safe */ + set_tss_desc(cpu, t); /* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */ + + load_TR(cpu); + +#if defined(CONFIG_X86_64) + /* Recover syscall MSRs */ + wrmsrl(MSR_LSTAR, saved_lstar); + wrmsrl(MSR_CSTAR, saved_cstar); + wrmsr(MSR_STAR, 0, (FLAT_RING3_CS32<<16) | __HYPERVISOR_CS); + wrmsr(MSR_SYSCALL_MASK, EF_VM|EF_RF|EF_NT|EF_DF|EF_IE|EF_TF, 0U); +#else /* !defined(CONFIG_X86_64) */ + if (supervisor_mode_kernel && cpu_has_sep) + wrmsr(MSR_IA32_SYSENTER_ESP, &t->esp1, 0); +#endif + + /* Maybe load the debug registers. */ + if ( !is_idle_vcpu(v) && unlikely(v->arch.guest_context.debugreg[7]) ) + { + loaddebug(&v->arch.guest_context, 0); + loaddebug(&v->arch.guest_context, 1); + loaddebug(&v->arch.guest_context, 2); + loaddebug(&v->arch.guest_context, 3); + /* no 4 and 5 */ + loaddebug(&v->arch.guest_context, 6); + loaddebug(&v->arch.guest_context, 7); + } + + /* Do we start fpu really? Just set cr0.ts to monitor it */ + stts(); + + mtrr_ap_init(); + mcheck_init(&boot_cpu_data); +} diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/x86/acpi/wakeup_prot.S --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/arch/x86/acpi/wakeup_prot.S Tue Jul 17 10:20:21 2007 +0100 @@ -0,0 +1,267 @@ + .text + +#include <xen/config.h> +#include <xen/multiboot.h> +#include <public/xen.h> +#include <asm/asm_defns.h> +#include <asm/desc.h> +#include <asm/page.h> +#include <asm/msr.h> + +#if defined(__x86_64__) + + .code64 + +#define GREG(x) %r##x +#define SAVED_GREG(x) saved_r##x(%rip) +#define DECLARE_GREG(x) saved_r##x: .quad 0 +#define SAVE_GREG(x) movq GREG(x), SAVED_GREG(x) +#define LOAD_GREG(x) movq SAVED_GREG(x), GREG(x) + +#define REF(x) x(%rip) + +#define RDMSR(ind, m) \ + xorq %rdx, %rdx; \ + mov $ind, %ecx; \ + rdmsr; \ + shlq $0x20, %rdx; \ + orq %rax, %rdx; \ + movq %rdx, m(%rip); + +#define WRMSR(ind, m) \ + mov $ind, %ecx; \ + movq m(%rip), %rdx; \ + mov %edx, %eax; \ + shrq $0x20, %rdx; \ + wrmsr; + +#else /* !defined(__x86_64__) */ + + .code32 + +#define GREG(x) %e##x +#define SAVED_GREG(x) saved_e##x +#define DECLARE_GREG(x) saved_e##x: .long 0 +#define SAVE_GREG(x) movl GREG(x), SAVED_GREG(x) +#define LOAD_GREG(x) movl SAVED_GREG(x), GREG(x) + +#define REF(x) x + +#endif + +ENTRY(do_suspend_lowlevel) + + SAVE_GREG(sp) + SAVE_GREG(ax) + SAVE_GREG(bx) + SAVE_GREG(cx) + SAVE_GREG(dx) + SAVE_GREG(bp) + SAVE_GREG(si) + SAVE_GREG(di) + +#if defined(__x86_64__) + + SAVE_GREG(8) # save r8...r15 + SAVE_GREG(9) + SAVE_GREG(10) + SAVE_GREG(11) + SAVE_GREG(12) + SAVE_GREG(13) + SAVE_GREG(14) + SAVE_GREG(15) + pushfq; + popq SAVED_GREG(flags) + + mov %cr8, GREG(ax) + mov GREG(ax), REF(saved_cr8) + + RDMSR(MSR_FS_BASE, saved_fs_base) + RDMSR(MSR_GS_BASE, saved_gs_base) + RDMSR(MSR_SHADOW_GS_BASE, saved_kernel_gs_base) + +#else /* !defined(__x86_64__) */ + + pushfl; + popl SAVED_GREG(flags) + +#endif + + mov %ds, REF(saved_ds) + mov %es, REF(saved_es) + mov %fs, REF(saved_fs) + mov %gs, REF(saved_gs) + mov %ss, REF(saved_ss) + + sgdt REF(saved_gdt) + sidt REF(saved_idt) + sldt REF(saved_ldt) + + mov %cr0, GREG(ax) + mov GREG(ax), REF(saved_cr0) + + mov %cr3, GREG(ax) + mov GREG(ax), REF(saved_cr3) + + call save_rest_processor_state + +#if defined(__x86_64__) + + mov $3, %rdi + xor %eax, %eax + +#else /* !defined(__x86_64__) */ + + push $3 + +#endif + + /* enter sleep state physically */ + call acpi_enter_sleep_state + jmp __ret_point + + .align 16 + .globl __ret_point +__ret_point: + + /* mmu_cr4_features contains latest cr4 setting */ + mov REF(mmu_cr4_features), GREG(ax) + mov GREG(ax), %cr4 + + mov REF(saved_cr3), GREG(ax) + mov GREG(ax), %cr3 + + mov REF(saved_cr0), GREG(ax) + mov GREG(ax), %cr0 + + lgdt REF(saved_gdt) + lidt REF(saved_idt) + lldt REF(saved_ldt) + + mov REF(saved_ss), %ss + LOAD_GREG(sp) + +#if defined(__x86_64__) + + mov REF(saved_cr8), %rax + mov %rax, %cr8 + + pushq SAVED_GREG(flags) + popfq + + /* Idle vcpu doesn't need segment selectors reload, since + * those may contain stale value from other domains and + * reload may result page fault due to no matched gdt entry + */ + mov $(STACK_SIZE - 8), %rax + or %rsp, %rax + and $~7, %rax + mov (%rax), %rax + mov 0x10(%rax), %rax + cmpw $0x7fff, (%rax) + je 1f + + /* These selectors are from guest, and thus need reload */ + mov REF(saved_ds), %ds + mov REF(saved_es), %es + mov REF(saved_fs), %fs + + /* gs load is special */ + mov REF(saved_gs), %rsi + mov $3, %rdi # SEGBASE_GS_USER_SEL + call do_set_segment_base + +1: + # MSR restore + WRMSR(MSR_FS_BASE, saved_fs_base) + WRMSR(MSR_GS_BASE, saved_gs_base) + WRMSR(MSR_SHADOW_GS_BASE, saved_kernel_gs_base) + +#else /* !defined(__x86_64__) */ + + pushl SAVED_GREG(flags) + popfl + + /* No reload to fs/gs, which is saved in bottom stack already */ + mov REF(saved_ds), %ds + mov REF(saved_es), %es + +#endif + + call restore_rest_processor_state + + LOAD_GREG(bp) + LOAD_GREG(ax) + LOAD_GREG(bx) + LOAD_GREG(cx) + LOAD_GREG(dx) + LOAD_GREG(si) + LOAD_GREG(di) +#if defined(__x86_64__) + LOAD_GREG(8) # save r8...r15 + LOAD_GREG(9) + LOAD_GREG(10) + LOAD_GREG(11) + LOAD_GREG(12) + LOAD_GREG(13) + LOAD_GREG(14) + LOAD_GREG(15) +#endif + ret + +.data + .align 16 +saved_ds: .word 0 +saved_es: .word 0 +saved_ss: .word 0 +saved_gs: .word 0 +saved_fs: .word 0 + + .align 4 + .globl saved_magic +saved_magic: .long 0x9abcdef0 + + .align 8 +DECLARE_GREG(sp) +DECLARE_GREG(bp) +DECLARE_GREG(ax) +DECLARE_GREG(bx) +DECLARE_GREG(cx) +DECLARE_GREG(dx) +DECLARE_GREG(si) +DECLARE_GREG(di) +DECLARE_GREG(flags) + +#if defined(__x86_64__) + +DECLARE_GREG(8) +DECLARE_GREG(9) +DECLARE_GREG(10) +DECLARE_GREG(11) +DECLARE_GREG(12) +DECLARE_GREG(13) +DECLARE_GREG(14) +DECLARE_GREG(15) + +saved_gdt: .quad 0,0 +saved_idt: .quad 0,0 +saved_ldt: .quad 0,0 + +saved_cr0: .quad 0 +saved_cr3: .quad 0 +saved_cr8: .quad 0 + +saved_gs_base: .quad 0 +saved_fs_base: .quad 0 +saved_kernel_gs_base: .quad 0 + +#else /* !defined(__x86_64__) */ + +saved_gdt: .long 0,0 +saved_idt: .long 0,0 +saved_ldt: .long 0 + +saved_cr0: .long 0 +saved_cr3: .long 0 + +#endif diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/x86/apic.c --- a/xen/arch/x86/apic.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/x86/apic.c Tue Jul 17 10:20:21 2007 +0100 @@ -957,7 +957,7 @@ void __setup_APIC_LVTT(unsigned int cloc apic_write_around(APIC_TMICT, clocks/APIC_DIVISOR); } -static void __init setup_APIC_timer(unsigned int clocks) +static void __devinit setup_APIC_timer(unsigned int clocks) { unsigned long flags; local_irq_save(flags); diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/x86/boot/Makefile --- a/xen/arch/x86/boot/Makefile Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/x86/boot/Makefile Tue Jul 17 10:20:21 2007 +0100 @@ -1,3 +1,4 @@ obj-y += head.o obj-y += head.o -head.o: head.S $(TARGET_SUBARCH).S trampoline.S mem.S video.S cmdline.S edd.S +head.o: head.S $(TARGET_SUBARCH).S trampoline.S mem.S video.S \ + cmdline.S edd.S wakeup.S diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/x86/boot/head.S --- a/xen/arch/x86/boot/head.S Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/x86/boot/head.S Tue Jul 17 10:20:21 2007 +0100 @@ -175,9 +175,11 @@ 1: stosl /* low mappings cover up #include "cmdline.S" + .align 16 .globl trampoline_start, trampoline_end trampoline_start: #include "trampoline.S" +#include "wakeup.S" trampoline_end: .text diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/x86/boot/wakeup.S --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/arch/x86/boot/wakeup.S Tue Jul 17 10:20:21 2007 +0100 @@ -0,0 +1,212 @@ + .code16 + +#undef wakesym +/* Used in real mode, to cal offset in current segment */ +#define wakesym(sym) (sym - wakeup_start) + +ENTRY(wakeup_start) + wakeup_code_start = . + + cli + cld + + # setup data segment + movw %cs, %ax + movw %ax, %ds + movw %ax, %ss # A stack required for BIOS call + movw $wakesym(wakeup_stack), %sp + + pushl $0 # Kill dangerous flag early + popfl + + # check magic number + movl wakesym(real_magic), %eax + cmpl $0x12345678, %eax + jne bogus_real_magic + + # for acpi_sleep=s3_bios + testl $1, wakesym(video_flags) + jz 1f + lcall $0xc000, $3 + movw %cs, %ax # In case messed by BIOS + movw %ax, %ds + movw %ax, %ss # Need this? How to ret if clobbered? + +1: # for acpi_sleep=s3_mode + testl $2, wakesym(video_flags) + jz 1f + movl wakesym(video_mode), %eax + call mode_setw + +1: # Show some progress if VGA is resumed + movw $0xb800, %ax + movw %ax, %fs + movw $0x0e00 + 'L', %fs:(0x10) + + # boot trampoline is under 1M, and shift its start into + # %fs to reference symbols in that area + movl $BOOT_TRAMPOLINE, %eax + shrl $4, %eax + movl %eax, %fs + lidt %fs:bootsym(idt_48) + lgdt %fs:bootsym(gdt_48) + + movw $1, %ax + lmsw %ax # Turn on CR0.PE + jmp 1f +1: ljmpl $BOOT_CS32, $bootsym_phys(wakeup_32) + +/* This code uses an extended set of video mode numbers. These include: + * Aliases for standard modes + * NORMAL_VGA (-1) + * EXTENDED_VGA (-2) + * ASK_VGA (-3) + * Video modes numbered by menu position -- NOT RECOMMENDED because of lack + * of compatibility when extending the table. These are between 0x00 and 0xff. + */ +#define VIDEO_FIRST_MENU 0x0000 + +/* Standard BIOS video modes (BIOS number + 0x0100) */ +#define VIDEO_FIRST_BIOS 0x0100 + +/* VESA BIOS video modes (VESA number + 0x0200) */ +#define VIDEO_FIRST_VESA 0x0200 + +/* Video7 special modes (BIOS number + 0x0900) */ +#define VIDEO_FIRST_V7 0x0900 + +# Setting of user mode (AX=mode ID) => CF=success +mode_setw: + movw %ax, %bx + cmpb $VIDEO_FIRST_VESA>>8, %ah + jnc check_vesaw + decb %ah + +setbadw: clc + ret + +check_vesaw: + subb $VIDEO_FIRST_VESA>>8, %bh + orw $0x4000, %bx # Use linear frame buffer + movw $0x4f02, %ax # VESA BIOS mode set call + int $0x10 + cmpw $0x004f, %ax # AL=4f if implemented + jnz _setbadw # AH=0 if OK + + stc + ret + +_setbadw: jmp setbadw + +bogus_real_magic: + movw $0x0e00 + 'B', %fs:(0x12) + jmp bogus_real_magic + + .align 4 +real_magic: .long 0x12345678 + .globl video_mode, video_flags +video_mode: .long 0 +video_flags: .long 0 + + .code32 + + # Now in protect mode, with paging disabled + # Add offset for any reference to xen specific symbols + +wakeup_32: + mov $BOOT_DS, %eax + mov %eax, %ds + mov %eax, %ss + mov $bootsym_phys(wakeup_stack), %esp + + # check saved magic again + mov $sym_phys(saved_magic), %eax + add bootsym_phys(trampoline_xen_phys_start), %eax + mov (%eax), %eax + cmp $0x9abcdef0, %eax + jne bogus_saved_magic + + /* fpu init? */ + + /* Initialise CR4. */ +#if CONFIG_PAGING_LEVELS == 2 + mov $X86_CR4_PSE, %ecx +#else + mov $X86_CR4_PAE, %ecx +#endif + mov %ecx, %cr4 + + /* Load pagetable base register */ + mov $sym_phys(idle_pg_table),%eax + add bootsym_phys(trampoline_xen_phys_start),%eax + mov %eax,%cr3 + + /* Will cpuid feature change after resume? */ +#if CONFIG_PAGING_LEVELS != 2 + /* Set up EFER (Extended Feature Enable Register). */ + mov bootsym_phys(cpuid_ext_features),%edi + test $0x20100800,%edi /* SYSCALL/SYSRET, No Execute, Long Mode? */ + jz .Lskip_eferw + movl $MSR_EFER,%ecx + rdmsr +#if CONFIG_PAGING_LEVELS == 4 + btsl $_EFER_LME,%eax /* Long Mode */ + btsl $_EFER_SCE,%eax /* SYSCALL/SYSRET */ +#endif + btl $20,%edi /* No Execute? */ + jnc 1f + btsl $_EFER_NX,%eax /* No Execute */ +1: wrmsr +.Lskip_eferw: +#endif + + wbinvd + + mov $0x80050033,%eax /* hi-to-lo: PG,AM,WP,NE,ET,MP,PE */ + mov %eax,%cr0 + jmp 1f +1: + +#if defined(__x86_64__) + + /* Now in compatibility mode. Long-jump to 64-bit mode */ + ljmp $BOOT_CS64, $bootsym_phys(wakeup_64) + + .code64 + .align 8 + .word 0,0,0 +lgdt_descr: + .word LAST_RESERVED_GDT_BYTE + .quad gdt_table - FIRST_RESERVED_GDT_BYTE + +wakeup_64: + lgdt lgdt_descr(%rip) + mov $(__HYPERVISOR_DS64), %eax + mov %eax, %ds + + # long jump to return point, with cs reload + rex64 ljmp *ret_point(%rip) + + .align 8 +ret_point: + .quad __ret_point + .word __HYPERVISOR_CS64 + +#else /* !defined(__x86_64__) */ + lgdt gdt_descr + mov $(__HYPERVISOR_DS), %eax + mov %eax, %ds + + ljmp $(__HYPERVISOR_CS), $__ret_point +#endif + +bogus_saved_magic: + movw $0x0e00 + 'S', 0xb8014 + jmp bogus_saved_magic + + .align 16 +wakeup_stack_begin: # Stack grows down + + .fill PAGE_SIZE,1,0 +wakeup_stack: # Just below end of first page in this section +ENTRY(wakeup_end) diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/x86/cpu/common.c --- a/xen/arch/x86/cpu/common.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/x86/cpu/common.c Tue Jul 17 10:20:21 2007 +0100 @@ -557,9 +557,6 @@ void __devinit cpu_init(void) } printk(KERN_INFO "Initializing CPU#%d\n", cpu); - if (cpu_has_vme || cpu_has_tsc || cpu_has_de) - clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); - *(unsigned short *)(&gdt_load[0]) = LAST_RESERVED_GDT_BYTE; *(unsigned long *)(&gdt_load[2]) = GDT_VIRT_START(current); __asm__ __volatile__ ( "lgdt %0" : "=m" (gdt_load) ); @@ -594,3 +591,11 @@ void __devinit cpu_init(void) /* Install correct page table. */ write_ptbase(current); } + +#ifdef CONFIG_HOTPLUG_CPU +void __cpuinit cpu_uninit(void) +{ + int cpu = raw_smp_processor_id(); + cpu_clear(cpu, cpu_initialized); +} +#endif diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/x86/crash.c --- a/xen/arch/x86/crash.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/x86/crash.c Tue Jul 17 10:20:21 2007 +0100 @@ -43,7 +43,7 @@ static int crash_nmi_callback(struct cpu kexec_crash_save_cpu(); disable_local_APIC(); atomic_dec(&waiting_for_crash_ipi); - hvm_disable(); + hvm_cpu_down(); for ( ; ; ) __asm__ __volatile__ ( "hlt" ); @@ -99,7 +99,7 @@ void machine_crash_shutdown(void) disable_IO_APIC(); - hvm_disable(); + hvm_cpu_down(); info = kexec_crash_save_info(); info->dom0_pfn_to_mfn_frame_list_list = diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/x86/dmi_scan.c --- a/xen/arch/x86/dmi_scan.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/x86/dmi_scan.c Tue Jul 17 10:20:21 2007 +0100 @@ -184,7 +184,6 @@ static __init int reset_videomode_after_ static __init int reset_videomode_after_s3(struct dmi_blacklist *d) { /* See acpi_wakeup.S */ - extern long acpi_video_flags; acpi_video_flags |= 2; return 0; } diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/x86/domain.c Tue Jul 17 10:20:21 2007 +0100 @@ -43,6 +43,7 @@ #include <asm/hvm/hvm.h> #include <asm/hvm/support.h> #include <asm/msr.h> +#include <asm/nmi.h> #ifdef CONFIG_COMPAT #include <compat/vcpu.h> #endif @@ -76,10 +77,28 @@ static void default_idle(void) local_irq_enable(); } +static void play_dead(void) +{ + __cpu_disable(); + /* This must be done before dead CPU ack */ + cpu_exit_clear(); + wbinvd(); + mb(); + /* Ack it */ + __get_cpu_var(cpu_state) = CPU_DEAD; + + /* With physical CPU hotplug, we should halt the cpu. */ + local_irq_disable(); + for ( ; ; ) + halt(); +} + void idle_loop(void) { for ( ; ; ) { + if (cpu_is_offline(smp_processor_id())) + play_dead(); page_scrub_schedule_work(); default_idle(); do_softirq(); diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/x86/domain_build.c --- a/xen/arch/x86/domain_build.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/x86/domain_build.c Tue Jul 17 10:20:21 2007 +0100 @@ -434,8 +434,7 @@ int __init construct_dom0( #ifdef __i386__ /* Ensure that our low-memory 1:1 mapping covers the allocation. */ - page = alloc_domheap_pages(d, order, - MEMF_bits(30 + (v_start >> 31))); + page = alloc_domheap_pages(d, order, MEMF_bits(30)); #else page = alloc_domheap_pages(d, order, 0); #endif diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/x86/domctl.c --- a/xen/arch/x86/domctl.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/x86/domctl.c Tue Jul 17 10:20:21 2007 +0100 @@ -427,6 +427,46 @@ long arch_do_domctl( } break; + case XEN_DOMCTL_sendtrigger: + { + struct domain *d; + struct vcpu *v; + + ret = -ESRCH; + if ( (d = rcu_lock_domain_by_id(domctl->domain)) == NULL ) + break; + + ret = -EINVAL; + if ( domctl->u.sendtrigger.vcpu >= MAX_VIRT_CPUS ) + goto sendtrigger_out; + + ret = -ESRCH; + if ( (v = d->vcpu[domctl->u.sendtrigger.vcpu]) == NULL ) + goto sendtrigger_out; + + switch ( domctl->u.sendtrigger.trigger ) + { + case XEN_DOMCTL_SENDTRIGGER_NMI: + { + ret = -ENOSYS; + if ( !is_hvm_domain(d) ) + break; + + ret = 0; + if ( !test_and_set_bool(v->arch.hvm_vcpu.nmi_pending) ) + vcpu_kick(v); + } + break; + + default: + ret = -ENOSYS; + } + + sendtrigger_out: + rcu_unlock_domain(d); + } + break; + default: ret = -ENOSYS; break; diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/x86/hvm/hvm.c Tue Jul 17 10:20:21 2007 +0100 @@ -74,12 +74,6 @@ void hvm_enable(struct hvm_function_tabl hvm_funcs = *fns; hvm_enabled = 1; -} - -void hvm_disable(void) -{ - if ( hvm_enabled ) - hvm_funcs.disable(); } void hvm_stts(struct vcpu *v) diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/x86/hvm/svm/svm.c Tue Jul 17 10:20:21 2007 +0100 @@ -94,9 +94,8 @@ static void svm_inject_exception(struct vmcb->eventinj = event; } -static void stop_svm(void) -{ - /* We turn off the EFER_SVME bit. */ +static void svm_cpu_down(void) +{ write_efer(read_efer() & ~EFER_SVME); } @@ -974,7 +973,7 @@ static int svm_event_injection_faulted(s static struct hvm_function_table svm_function_table = { .name = "SVM", - .disable = stop_svm, + .cpu_down = svm_cpu_down, .domain_initialise = svm_domain_initialise, .domain_destroy = svm_domain_destroy, .vcpu_initialise = svm_vcpu_initialise, @@ -2329,9 +2328,6 @@ static int svm_reset_to_realmode(struct /* clear the vmcb and user regs */ memset(regs, 0, sizeof(struct cpu_user_regs)); - /* VMCB Control */ - vmcb->tsc_offset = 0; - /* VMCB State */ vmcb->cr0 = X86_CR0_ET | X86_CR0_PG | X86_CR0_WP; v->arch.hvm_svm.cpu_shadow_cr0 = X86_CR0_ET; diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/x86/hvm/svm/vmcb.c --- a/xen/arch/x86/hvm/svm/vmcb.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/x86/hvm/svm/vmcb.c Tue Jul 17 10:20:21 2007 +0100 @@ -239,11 +239,11 @@ static int construct_vmcb(struct vcpu *v (HVM_CR4_HOST_MASK & ~X86_CR4_PAE); vmcb->exception_intercepts = HVM_TRAP_MASK; - /* No point in intercepting CR0/3/4 reads, because the hardware - * will return the guest versions anyway. */ - vmcb->cr_intercepts &= ~(CR_INTERCEPT_CR0_READ - |CR_INTERCEPT_CR3_READ - |CR_INTERCEPT_CR4_READ); + /* No point in intercepting CR3/4 reads, because the hardware + * will return the guest versions anyway. Still need to intercept + * CR0 reads to hide the changes we make to CR0.TS in the lazy-fpu + * code. */ + vmcb->cr_intercepts &= ~(CR_INTERCEPT_CR3_READ|CR_INTERCEPT_CR4_READ); /* No point in intercepting INVLPG if we don't have shadow pagetables * that need to be fixed up. */ diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/x86/hvm/vlapic.c --- a/xen/arch/x86/hvm/vlapic.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/x86/hvm/vlapic.c Tue Jul 17 10:20:21 2007 +0100 @@ -915,10 +915,17 @@ int vlapic_init(struct vcpu *v) int vlapic_init(struct vcpu *v) { struct vlapic *vlapic = vcpu_vlapic(v); + unsigned int memflags = 0; HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "%d", v->vcpu_id); - vlapic->regs_page = alloc_domheap_page(NULL); +#ifdef __i386__ + /* 32-bit VMX may be limited to 32-bit physical addresses. */ + if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL ) + memflags = MEMF_bits(32); +#endif + + vlapic->regs_page = alloc_domheap_pages(NULL, 0, memflags); if ( vlapic->regs_page == NULL ) { dprintk(XENLOG_ERR, "alloc vlapic regs error: %d/%d\n", diff -r c9720159b983 -r 9559ba7c80f9 xen/arch/x86/hvm/vmx/vmcs.c --- a/xen/arch/x86/hvm/vmx/vmcs.c Mon Jul 16 14:20:16 2007 -0500 +++ b/xen/arch/x86/hvm/vmx/vmcs.c Tue Jul 17 10:20:21 2007 +0100 @@ -45,7 +45,9 @@ u32 vmx_vmentry_control __read_mostly; u32 vmx_vmentry_control __read_mostly; bool_t cpu_has_vmx_ins_outs_instr_info __read_mostly; +static DEFINE_PER_CPU(struct vmcs_struct *, host_vmcs); static DEFINE_PER_CPU(struct vmcs_struct *, current_vmcs); +static DEFINE_PER_CPU(struct list_head, active_vmcs_list); static u32 vmcs_revision_id __read_mostly; @@ -64,7 +66,7 @@ static u32 adjust_vmx_controls(u32 ctl_m return ctl; } -void vmx_init_vmcs_config(void) +static void vmx_init_vmcs_config(void) { u32 vmx_msr_low, vmx_msr_high, min, opt; u32 _vmx_pin_based_exec_control; @@ -128,8 +130,9 @@ void vmx_init_vmcs_config(void) rdmsr(MSR_IA32_VMX_BASIC, vmx_msr_low, vmx_msr_high); - if ( smp_processor_id() == 0 ) - { + if ( !vmx_pin_based_exec_control ) + { + /* First time through. */ vmcs_revision_id = vmx_msr_low; vmx_pin_based_exec_control = _vmx_pin_based_exec_control; vmx_cpu_based_exec_control = _vmx_cpu_based_exec_control; @@ -140,6 +143,7 @@ void vmx_init_vmcs_config(void) } else { + /* Globals are already initialised: re-check them. */ BUG_ON(vmcs_revision_id != vmx_msr_low); BUG_ON(vmx_pin_based_exec_control != _vmx_pin_based_exec_control); BUG_ON(vmx_cpu_based_exec_control != _vmx_cpu_based_exec_control); @@ -151,6 +155,14 @@ void vmx_init_vmcs_config(void) /* IA-32 SDM Vol 3B: VMCS size is never greater than 4kB. */ BUG_ON((vmx_msr_high & 0x1fff) > PAGE_SIZE); + +#ifdef __x86_64__ + /* IA-32 SDM Vol 3B: 64-bit CPUs always have VMX_BASIC_MSR[48]==0. */ + BUG_ON(vmx_msr_high & (1u<<16)); +#endif + + /* Require Write-Back (WB) memory type for VMCS accesses. */ + BUG_ON(((vmx_msr_high >> 18) & 15) != 6); } static struct vmcs_struct *vmx_alloc_vmcs(void) @@ -177,34 +189,115 @@ static void __vmx_clear_vmcs(void *info) static void __vmx_clear_vmcs(void *info) { struct vcpu *v = info; - - __vmpclear(virt_to_maddr(v->arch.hvm_vmx.vmcs)); - - v->arch.hvm_vmx.active_cpu = -1; - v->arch.hvm_vmx.launched = 0; - - if ( v->arch.hvm_vmx.vmcs == this_cpu(current_vmcs) ) - this_cpu(current_vmcs) = NULL; + struct arch_vmx_struct *arch_vmx = &v->arch.hvm_vmx; + + /* Otherwise we can nest (vmx_cpu_down() vs. vmx_clear_vmcs()). */ + ASSERT(!local_irq_is_enabled()); + + if ( arch_vmx->active_cpu == smp_processor_id() ) + { + __vmpclear(virt_to_maddr(arch_vmx->vmcs)); + + arch_vmx->active_cpu = -1; + arch_vmx->launched = 0; + + list_del(&arch_vmx->active_list); + + if ( arch_vmx->vmcs == this_cpu(current_vmcs) ) + this_cpu(current_vmcs) = NULL; + } } static void vmx_clear_vmcs(struct vcpu *v) { int cpu = v->arch.hvm_vmx.active_cpu; - if ( cpu == -1 ) - return; - - if ( cpu == smp_processor_id() ) - return __vmx_clear_vmcs(v); - - on_selected_cpus(cpumask_of_cpu(cpu), __vmx_clear_vmcs, v, 1, 1); + if ( cpu != -1 ) + on_selected_cpus(cpumask_of_cpu(cpu), __vmx_clear_vmcs, v, 1, 1); } static void vmx_load_vmcs(struct vcpu *v) { + unsigned long flags; + + local_irq_save(flags); + + if ( v->arch.hvm_vmx.active_cpu == -1 ) + { + list_add(&v->arch.hvm_vmx.active_list, &this_cpu(active_vmcs_list)); + v->arch.hvm_vmx.active_cpu = smp_processor_id(); + } + + ASSERT(v->arch.hvm_vmx.active_cpu == smp_processor_id()); + __vmptrld(virt_to_maddr(v->arch.hvm_vmx.vmcs)); - v->arch.hvm_vmx.active_cpu = smp_processor_id(); this_cpu(current_vmcs) = v->arch.hvm_vmx.vmcs; + + local_irq_restore(flags); +} + +int vmx_cpu_up(void) +{ + u32 eax, edx; + int cpu = smp_processor_id(); + + BUG_ON(!(read_cr4() & X86_CR4_VMXE)); + + rdmsr(IA32_FEATURE_CONTROL_MSR, eax, edx); + + if ( eax & IA32_FEATURE_CONTROL_MSR_LOCK ) + { + if ( !(eax & IA32_FEATURE_CONTROL_MSR_ENABLE_VMXON) ) + { + printk("CPU%d: VMX disabled\n", cpu); + return 0; + } + } + else + { + wrmsr(IA32_FEATURE_CONTROL_MSR, + IA32_FEATURE_CONTROL_MSR_LOCK | + IA32_FEATURE_CONTROL_MSR_ENABLE_VMXON, 0); + } + + vmx_init_vmcs_config(); + + INIT_LIST_HEAD(&this_cpu(active_vmcs_list)); + + if ( this_cpu(host_vmcs) == NULL ) + { + this_cpu(host_vmcs) = vmx_alloc_vmcs(); + if ( this_cpu(host_vmcs) == NULL ) + { + printk("CPU%d: Could not allocate host VMCS\n", cpu); + return 0; + } + } + + if ( __vmxon(virt_to_maddr(this_cpu(host_vmcs))) ) + { + printk("CPU%d: VMXON failed\n", cpu); + return 0; + } + + return 1; +} + +void vmx_cpu_down(void) +{ + struct list_head *active_vmcs_list = &this_cpu(active_vmcs_list); + unsigned long flags; + + local_irq_save(flags); + + while ( !list_empty(active_vmcs_list) ) + __vmx_clear_vmcs(list_entry(active_vmcs_list->next, + struct vcpu, arch.hvm_vmx.active_list)); + + BUG_ON(!(read_cr4() & X86_CR4_VMXE)); + __vmxoff(); + + local_irq_restore(flags); } void vmx_vmcs_enter(struct vcpu *v) @@ -237,65 +330,27 @@ void vmx_vmcs_exit(struct vcpu *v) vcpu_unpause(v); } -struct vmcs_struct *vmx_alloc_host_vmcs(void) -{ - return vmx_alloc_vmcs(); -} - -void vmx_free_host_vmcs(struct vmcs_struct *vmcs) -{ - vmx_free_vmcs(vmcs); -} - -#define GUEST_SEGMENT_LIMIT 0xffffffff - -struct host_execution_env { - /* selectors */ - unsigned short ldtr_selector; - unsigned short tr_selector; - unsigned short ds_selector; - unsigned short cs_selector; - /* limits */ - unsigned short gdtr_limit; - unsigned short ldtr_limit; - unsigned short idtr_limit; - unsigned short tr_limit; - /* base */ - unsigned long gdtr_base; - unsigned long ldtr_base; - unsigned long idtr_base; - unsigned long tr_base; - unsigned long ds_base; - unsigned long cs_base; -#ifdef __x86_64__ - unsigned long fs_base; - unsigned long gs_base; -#endif +struct xgt_desc { + unsigned short size; + unsigned long address __attribute__((packed)); }; static void vmx_set_host_env(struct vcpu *v) { unsigned int tr, cpu; - struct host_execution_env host_env; - struct Xgt_desc_struct desc; + struct xgt_desc desc; cpu = smp_processor_id(); - __asm__ __volatile__ ("sidt (%0) \n" :: "a"(&desc) : "memory"); - host_env.idtr_limit = desc.size; - host_env.idtr_base = desc.address; - __vmwrite(HOST_IDTR_BASE, host_env.idtr_base); - - __asm__ __volatile__ ("sgdt (%0) \n" :: "a"(&desc) : "memory"); - host_env.gdtr_limit = desc.size; - host_env.gdtr_base = desc.address; - __vmwrite(HOST_GDTR_BASE, host_env.gdtr_base); - - __asm__ __volatile__ ("str (%0) \n" :: "a"(&tr) : "memory"); - host_env.tr_selector = tr; - host_env.tr_limit = sizeof(struct tss_struct); - host_env.tr_base = (unsigned long) &init_tss[cpu]; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |