WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] merge with xen-unstable.hg

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 22 Oct 2008 07:51:14 -0700
Delivery-date: Wed, 22 Oct 2008 07:55:23 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
# Date 1224643615 -32400
# Node ID 46d7e12c4c919bab07af4b7097526dd06b824bea
# Parent  6583186e5989d7e7e0bff126cd20a9cacb7c1613
# Parent  d2f7243fc571ea78cbf3fe33e723aa8f30111daa
merge with xen-unstable.hg
---
 xen/include/asm-ia64/xenspinlock.h                         |   30 
 docs/xen-api/coversheet.tex                                |    1 
 docs/xen-api/revision-history.tex                          |    9 
 docs/xen-api/xenapi-coversheet.tex                         |    4 
 docs/xen-api/xenapi-datamodel-graph.dot                    |   11 
 docs/xen-api/xenapi-datamodel.tex                          | 1160 +++++++++++++
 tools/blktap/drivers/block-qcow.c                          |   18 
 tools/blktap/drivers/block-qcow2.c                         |   62 
 tools/libxc/xc_domain.c                                    |   12 
 tools/libxc/xenctrl.h                                      |    3 
 tools/python/xen/lowlevel/xc/xc.c                          |   21 
 tools/python/xen/util/pci.py                               |   21 
 tools/python/xen/util/utils.py                             |   26 
 tools/python/xen/util/vscsi_util.py                        |  219 +-
 tools/python/xen/xend/XendAPI.py                           |   20 
 tools/python/xen/xend/XendConfig.py                        |  202 +-
 tools/python/xen/xend/XendDSCSI.py                         |  174 +
 tools/python/xen/xend/XendDomainInfo.py                    |  137 +
 tools/python/xen/xend/XendNode.py                          |   39 
 tools/python/xen/xend/XendPSCSI.py                         |  143 +
 tools/python/xen/xend/server/vscsiif.py                    |   18 
 tools/python/xen/xm/create.dtd                             |    5 
 tools/python/xen/xm/create.py                              |   18 
 tools/python/xen/xm/main.py                                |  140 +
 tools/python/xen/xm/xenapi_create.py                       |   59 
 tools/xentrace/formats                                     |    4 
 unmodified_drivers/linux-2.6/platform-pci/machine_reboot.c |   14 
 xen/arch/ia64/vmx/vmmu.c                                   |    2 
 xen/arch/x86/acpi/cpu_idle.c                               |   15 
 xen/arch/x86/cpu/amd.c                                     |    4 
 xen/arch/x86/domain.c                                      |    7 
 xen/arch/x86/domctl.c                                      |   15 
 xen/arch/x86/hvm/svm/emulate.c                             |   31 
 xen/arch/x86/hvm/svm/intr.c                                |   57 
 xen/arch/x86/hvm/viridian.c                                |    3 
 xen/arch/x86/hvm/vmx/intr.c                                |   57 
 xen/arch/x86/hvm/vmx/vmx.c                                 |   20 
 xen/arch/x86/irq.c                                         |   55 
 xen/arch/x86/mm/hap/hap.c                                  |    7 
 xen/arch/x86/mm/shadow/private.h                           |   63 
 xen/arch/x86/msi.c                                         |    1 
 xen/arch/x86/nmi.c                                         |   25 
 xen/arch/x86/platform_hypercall.c                          |   22 
 xen/arch/x86/smpboot.c                                     |   13 
 xen/arch/x86/traps.c                                       |    6 
 xen/arch/x86/x86_32/xen.lds.S                              |    1 
 xen/arch/x86/x86_64/Makefile                               |    2 
 xen/arch/x86/x86_64/cpu_idle.c                             |    2 
 xen/arch/x86/x86_64/cpufreq.c                              |   91 +
 xen/arch/x86/x86_64/mm.c                                   |    2 
 xen/arch/x86/x86_64/platform_hypercall.c                   |    4 
 xen/arch/x86/x86_64/xen.lds.S                              |    1 
 xen/arch/x86/x86_emulate/x86_emulate.c                     |    9 
 xen/common/Makefile                                        |    3 
 xen/common/kernel.c                                        |    3 
 xen/common/schedule.c                                      |    4 
 xen/common/spinlock.c                                      |  154 +
 xen/common/timer.c                                         |   56 
 xen/common/xmalloc_tlsf.c                                  |  599 ++++++
 xen/drivers/Makefile                                       |    2 
 xen/drivers/acpi/pmstat.c                                  |    4 
 xen/drivers/char/ns16550.c                                 |   19 
 xen/drivers/cpufreq/cpufreq.c                              |   35 
 xen/drivers/cpufreq/utility.c                              |   37 
 xen/drivers/passthrough/Makefile                           |    1 
 xen/drivers/passthrough/io.c                               |   61 
 xen/drivers/passthrough/iommu.c                            |    2 
 xen/drivers/passthrough/pci.c                              |    5 
 xen/drivers/passthrough/vtd/Makefile                       |    1 
 xen/drivers/passthrough/vtd/ia64/Makefile                  |    1 
 xen/drivers/passthrough/vtd/ia64/vtd.c                     |  112 +
 xen/drivers/passthrough/vtd/intremap.c                     |   54 
 xen/drivers/passthrough/vtd/iommu.c                        |  125 -
 xen/drivers/passthrough/vtd/qinval.c                       |    6 
 xen/drivers/passthrough/vtd/utils.c                        |    5 
 xen/drivers/passthrough/vtd/x86/vtd.c                      |    8 
 xen/include/acpi/cpufreq/processor_perf.h                  |    3 
 xen/include/asm-ia64/linux-xen/asm/spinlock.h              |   49 
 xen/include/asm-x86/domain.h                               |    2 
 xen/include/asm-x86/hvm/hvm.h                              |    7 
 xen/include/asm-x86/hvm/irq.h                              |   78 
 xen/include/asm-x86/hvm/svm/vmcb.h                         |    4 
 xen/include/asm-x86/io_apic.h                              |    2 
 xen/include/asm-x86/msi.h                                  |    9 
 xen/include/asm-x86/rwlock.h                               |   32 
 xen/include/asm-x86/spinlock.h                             |   95 -
 xen/include/public/domctl.h                                |    4 
 xen/include/public/trace.h                                 |   10 
 xen/include/xen/hvm/irq.h                                  |   99 +
 xen/include/xen/spinlock.h                                 |  156 -
 xen/include/xen/xmalloc.h                                  |   81 
 xen/include/xlat.lst                                       |    4 
 92 files changed, 4067 insertions(+), 950 deletions(-)

diff -r 6583186e5989 -r 46d7e12c4c91 docs/xen-api/coversheet.tex
--- a/docs/xen-api/coversheet.tex       Wed Oct 22 11:38:22 2008 +0900
+++ b/docs/xen-api/coversheet.tex       Wed Oct 22 11:46:55 2008 +0900
@@ -51,6 +51,7 @@ Mike Day, IBM & Daniel Veillard, Red Hat
 Mike Day, IBM & Daniel Veillard, Red Hat \\
 Jim Fehlig, Novell & Tom Wilkie, University of Cambridge \\
 Jon Harrop, XenSource & Yosuke Iwamatsu, NEC \\
+Masaki Kanno, FUJITSU \\
 \end{tabular}
 \end{large}
 
diff -r 6583186e5989 -r 46d7e12c4c91 docs/xen-api/revision-history.tex
--- a/docs/xen-api/revision-history.tex Wed Oct 22 11:38:22 2008 +0900
+++ b/docs/xen-api/revision-history.tex Wed Oct 22 11:46:55 2008 +0900
@@ -56,5 +56,14 @@
     \end{flushleft}
    \end{minipage}\\
   \hline
+  1.0.7 & 20th Oct. 08 & M. Kanno &
+   \begin{minipage}[t]{7cm}
+    \begin{flushleft}
+     Added definitions of new classes DSCSI and PSCSI. Updated the table
+     and the diagram representing relationships between classes.
+     Added host.PSCSIs and VM.DSCSIs fields.
+    \end{flushleft}
+   \end{minipage}\\
+  \hline
  \end{tabular}
 \end{center}
diff -r 6583186e5989 -r 46d7e12c4c91 docs/xen-api/xenapi-coversheet.tex
--- a/docs/xen-api/xenapi-coversheet.tex        Wed Oct 22 11:38:22 2008 +0900
+++ b/docs/xen-api/xenapi-coversheet.tex        Wed Oct 22 11:46:55 2008 +0900
@@ -17,12 +17,12 @@
 \newcommand{\coversheetlogo}{xen.eps}
 
 %% Document date
-\newcommand{\datestring}{24th July 2008}
+\newcommand{\datestring}{20th October 2008}
 
 \newcommand{\releasestatement}{Stable Release}
 
 %% Document revision
-\newcommand{\revstring}{API Revision 1.0.6}
+\newcommand{\revstring}{API Revision 1.0.7}
 
 %% Document authors
 \newcommand{\docauthors}{
diff -r 6583186e5989 -r 46d7e12c4c91 docs/xen-api/xenapi-datamodel-graph.dot
--- a/docs/xen-api/xenapi-datamodel-graph.dot   Wed Oct 22 11:38:22 2008 +0900
+++ b/docs/xen-api/xenapi-datamodel-graph.dot   Wed Oct 22 11:46:55 2008 +0900
@@ -12,9 +12,11 @@ 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 
XSPolicy ACMPolicy;
-node [shape=ellipse]; PIF_metrics VIF_metrics VM_metrics VBD_metrics 
PBD_metrics VM_guest_metrics host_metrics;
-node [shape=box]; DPCI PPCI host_cpu console VTPM
+node [ shape=box ]; session VM host network VIF PIF SR VDI VBD PBD user;
+node [ shape=box ]; XSPolicy ACMPolicy DPCI PPCI host_cpu console VTPM;
+node [ shape=box ]; DSCSI PSCSI;
+node [ shape=ellipse ]; VM_metrics VM_guest_metrics host_metrics;
+node [ shape=ellipse ]; PIF_metrics VIF_metrics VBD_metrics PBD_metrics;
 session -> host [ arrowhead="none" ]
 session -> user [ arrowhead="none" ]
 VM -> VM_metrics [ arrowhead="none" ]
@@ -41,4 +43,7 @@ DPCI -> VM [ arrowhead="none", arrowtail
 DPCI -> VM [ arrowhead="none", arrowtail="crow" ]
 DPCI -> PPCI [ arrowhead="none" ]
 PPCI -> host [ arrowhead="none", arrowtail="crow" ]
+DSCSI -> VM [ arrowhead="none", arrowtail="crow" ]
+DSCSI -> PSCSI [ arrowhead="none" ]
+PSCSI -> host [ arrowhead="none", arrowtail="crow" ]
 }
diff -r 6583186e5989 -r 46d7e12c4c91 docs/xen-api/xenapi-datamodel.tex
--- a/docs/xen-api/xenapi-datamodel.tex Wed Oct 22 11:38:22 2008 +0900
+++ b/docs/xen-api/xenapi-datamodel.tex Wed Oct 22 11:46:55 2008 +0900
@@ -46,6 +46,8 @@ Name & Description \\
 {\tt console} & A console \\
 {\tt DPCI} & A pass-through PCI device \\
 {\tt PPCI} & A physical PCI device \\
+{\tt DSCSI} & A half-virtualized SCSI device \\
+{\tt PSCSI} & A physical SCSI device \\
 {\tt user} & A user of the system \\
 {\tt debug} & A basic class for testing \\
 {\tt XSPolicy} & A class for handling Xen Security Policies \\
@@ -74,6 +76,8 @@ console.VM & VM.consoles & one-to-many\\
 console.VM & VM.consoles & one-to-many\\
 DPCI.VM & VM.DPCIs & one-to-many\\
 PPCI.host & host.PPCIs & one-to-many\\
+DSCSI.VM & VM.DSCSIs & one-to-many\\
+PSCSI.host & host.PSCSIs & one-to-many\\
 host.resident\_VMs & VM.resident\_on & many-to-one\\
 host.host\_CPUs & host\_cpu.host & many-to-one\\
 \hline
@@ -1407,6 +1411,7 @@ Quals & Field & Type & Description \\
 $\mathit{RO}_\mathit{run}$ &  {\tt crash\_dumps} & (crashdump ref) Set & crash 
dumps associated with this VM \\
 $\mathit{RO}_\mathit{run}$ &  {\tt VTPMs} & (VTPM ref) Set & virtual TPMs \\
 $\mathit{RO}_\mathit{run}$ &  {\tt DPCIs} & (DPCI ref) Set & pass-through PCI 
devices \\
+$\mathit{RO}_\mathit{run}$ &  {\tt DSCSIs} & (DSCSI ref) Set & 
half-virtualized SCSI devices \\
 $\mathit{RW}$ &  {\tt PV/bootloader} & string & name of or path to bootloader 
\\
 $\mathit{RW}$ &  {\tt PV/kernel} & string & path to the kernel \\
 $\mathit{RW}$ &  {\tt PV/ramdisk} & string & path to the initrd \\
@@ -3443,6 +3448,38 @@ Get the DPCIs field of the given VM.
  \noindent {\bf Return Type:} 
 {\tt 
 (DPCI ref) Set
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_DSCSIs}
+
+{\bf Overview:} 
+Get the DSCSIs field of the given VM.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} ((DSCSI ref) Set) get_DSCSIs (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 
+(DSCSI ref) Set
 }
 
 
@@ -5518,6 +5555,7 @@ Quals & Field & Type & Description \\
 $\mathit{RW}$ &  {\tt crash\_dump\_sr} & SR ref & The SR in which VDIs for 
crash dumps are created \\
 $\mathit{RO}_\mathit{run}$ &  {\tt PBDs} & (PBD ref) Set & physical 
blockdevices \\
 $\mathit{RO}_\mathit{run}$ &  {\tt PPCIs} & (PPCI ref) Set & physical PCI 
devices \\
+$\mathit{RO}_\mathit{run}$ &  {\tt PSCSIs} & (PSCSI ref) Set & physical SCSI 
devices \\
 $\mathit{RO}_\mathit{run}$ &  {\tt host\_CPUs} & (host\_cpu ref) Set & The 
physical CPUs on this host \\
 $\mathit{RO}_\mathit{run}$ &  {\tt metrics} & host\_metrics ref & metrics 
associated with this host \\
 \hline
@@ -6837,6 +6875,38 @@ Get the PPCIs field of the given host.
  \noindent {\bf Return Type:} 
 {\tt 
 (PPCI ref) Set
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_PSCSIs}
+
+{\bf Overview:} 
+Get the PSCSIs field of the given host.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} ((PSCSI ref) Set) get_PSCSIs (session_id s, host 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 host ref } & self & reference to the object \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+(PSCSI ref) Set
 }
 
 
@@ -15723,6 +15793,1096 @@ all fields from the object
 
 \vspace{1cm}
 \newpage
+\section{Class: DSCSI}
+\subsection{Fields for class: DSCSI}
+\begin{longtable}{|lllp{0.38\textwidth}|}
+\hline
+\multicolumn{1}{|l}{Name} & \multicolumn{3}{l|}{\bf DSCSI} \\
+\multicolumn{1}{|l}{Description} & \multicolumn{3}{l|}{\parbox{11cm}{\em A
+half-virtualized SCSI device.}} \\
+\hline
+Quals & Field & Type & Description \\
+\hline
+$\mathit{RO}_\mathit{run}$ &  {\tt uuid} & string & unique identifier/object 
reference \\
+$\mathit{RO}_\mathit{inst}$ &  {\tt VM} & VM ref & the virtual machine \\
+$\mathit{RO}_\mathit{inst}$ &  {\tt PSCSI} & PSCSI ref & the physical SCSI 
device \\
+$\mathit{RO}_\mathit{run}$ &  {\tt virtual\_host} & int & the virtual host 
number \\
+$\mathit{RO}_\mathit{run}$ &  {\tt virtual\_channel} & int & the virtual 
channel number \\
+$\mathit{RO}_\mathit{run}$ &  {\tt virtual\_target} & int & the virtual target 
number \\
+$\mathit{RO}_\mathit{run}$ &  {\tt virtual\_lun} & int & the virtual logical 
unit number \\
+$\mathit{RO}_\mathit{inst}$ &  {\tt virtual\_HCTL} & string & the virtual HCTL 
\\
+$\mathit{RO}_\mathit{run}$ &  {\tt runtime\_properties} & (string 
$\rightarrow$ string) Map & Device runtime properties \\
+\hline
+\end{longtable}
+\subsection{RPCs associated with class: DSCSI}
+\subsubsection{RPC name:~get\_all}
+
+{\bf Overview:} 
+Return a list of all the DSCSIs known to the system.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} ((DSCSI ref) Set) get_all (session_id s)\end{verbatim}
+
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+(DSCSI ref) Set
+}
+
+
+references to all objects
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_uuid}
+
+{\bf Overview:} 
+Get the uuid field of the given DSCSI.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} string get_uuid (session_id s, DSCSI 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 DSCSI 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\_VM}
+
+{\bf Overview:} 
+Get the VM field of the given DSCSI.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} (VM ref) get_VM (session_id s, DSCSI 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 DSCSI ref } & self & reference to the object \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+VM ref
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_PSCSI}
+
+{\bf Overview:} 
+Get the PSCSI field of the given DSCSI.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} (PSCSI ref) get_PSCSI (session_id s, DSCSI 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 DSCSI ref } & self & reference to the object \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+PSCSI ref
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_virtual\_host}
+
+{\bf Overview:} 
+Get the virtual\_host field of the given DSCSI.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} int get_virtual_host (session_id s, DSCSI 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 DSCSI ref } & self & reference to the object \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+int
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_virtual\_channel}
+
+{\bf Overview:} 
+Get the virtual\_channel field of the given DSCSI.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} int get_virtual_channel (session_id s, DSCSI 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 DSCSI ref } & self & reference to the object \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+int
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_virtual\_target}
+
+{\bf Overview:} 
+Get the virtual\_target field of the given DSCSI.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} int get_virtual_target (session_id s, DSCSI 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 DSCSI ref } & self & reference to the object \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+int
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_virtual\_lun}
+
+{\bf Overview:} 
+Get the virtual\_lun field of the given DSCSI.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} int get_virtual_lun (session_id s, DSCSI 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 DSCSI ref } & self & reference to the object \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+int
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_virtual\_HCTL}
+
+{\bf Overview:} 
+Get the virtual\_HCTL field of the given DSCSI.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} string get_virtual_HCTL (session_id s, DSCSI 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 DSCSI 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\_runtime\_properties}
+
+{\bf Overview:} 
+Get the runtime\_properties field of the given DSCSI.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} ((string -> string) Map) get_runtime_properties (session_id 
s, DSCSI 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 DSCSI 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:} 
+Create a new DSCSI instance, and return its handle.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} (DSCSI ref) create (session_id s, DSCSI record 
args)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt DSCSI record } & args & All constructor arguments \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+DSCSI ref
+}
+
+
+reference to the newly created object
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~destroy}
+
+{\bf Overview:} 
+Destroy the specified DSCSI instance.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} void destroy (session_id s, DSCSI 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 DSCSI ref } & self & reference to the object \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+void
+}
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_by\_uuid}
+
+{\bf Overview:} 
+Get a reference to the DSCSI instance with the specified UUID.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} (DSCSI ref) get_by_uuid (session_id s, string 
uuid)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt string } & uuid & UUID of object to return \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+DSCSI ref
+}
+
+
+reference to the object
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_record}
+
+{\bf Overview:} 
+Get a record containing the current state of the given DSCSI.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} (DSCSI record) get_record (session_id s, DSCSI 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 DSCSI ref } & self & reference to the object \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+DSCSI record
+}
+
+
+all fields from the object
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+
+\vspace{1cm}
+\newpage
+\section{Class: PSCSI}
+\subsection{Fields for class: PSCSI}
+\begin{longtable}{|lllp{0.38\textwidth}|}
+\hline
+\multicolumn{1}{|l}{Name} & \multicolumn{3}{l|}{\bf PSCSI} \\
+\multicolumn{1}{|l}{Description} & \multicolumn{3}{l|}{\parbox{11cm}{\em A
+physical SCSI device.}} \\
+\hline
+Quals & Field & Type & Description \\
+\hline
+$\mathit{RO}_\mathit{run}$ &  {\tt uuid} & string & unique identifier/object 
reference \\
+$\mathit{RO}_\mathit{run}$ &  {\tt host} & host ref &  the physical machine to 
which this PSCSI is connected \\
+$\mathit{RO}_\mathit{run}$ &  {\tt physical\_host} & int & the physical host 
number \\
+$\mathit{RO}_\mathit{run}$ &  {\tt physical\_channel} & int & the physical 
channel number \\
+$\mathit{RO}_\mathit{run}$ &  {\tt physical\_target} & int & the physical 
target number \\
+$\mathit{RO}_\mathit{run}$ &  {\tt physical\_lun} & int & the physical logical 
unit number \\
+$\mathit{RO}_\mathit{run}$ &  {\tt physical\_HCTL} & string & the physical 
HCTL \\
+$\mathit{RO}_\mathit{run}$ &  {\tt vendor\_name} & string & the vendor name \\
+$\mathit{RO}_\mathit{run}$ &  {\tt model} & string & the model \\
+$\mathit{RO}_\mathit{run}$ &  {\tt type\_id} & int & the SCSI type ID \\
+$\mathit{RO}_\mathit{run}$ &  {\tt type} & string &  the SCSI type \\
+$\mathit{RO}_\mathit{run}$ &  {\tt dev\_name} & string & the SCSI device name 
(e.g. sda or st0) \\
+$\mathit{RO}_\mathit{run}$ &  {\tt sg\_name} & string & the SCSI generic 
device name (e.g. sg0) \\
+$\mathit{RO}_\mathit{run}$ &  {\tt revision} & string & the revision \\
+$\mathit{RO}_\mathit{run}$ &  {\tt scsi\_id} & string & the SCSI ID \\
+$\mathit{RO}_\mathit{run}$ &  {\tt scsi\_level} & int & the SCSI level \\
+\hline
+\end{longtable}
+\subsection{RPCs associated with class: PSCSI}
+\subsubsection{RPC name:~get\_all}
+
+{\bf Overview:} 
+Return a list of all the PSCSIs known to the system.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} ((PSCSI ref) Set) get_all (session_id s)\end{verbatim}
+
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+(PSCSI ref) Set
+}
+
+
+references to all objects
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_uuid}
+
+{\bf Overview:} 
+Get the uuid field of the given PSCSI.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} string get_uuid (session_id s, PSCSI 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 PSCSI 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\_host}
+
+{\bf Overview:} 
+Get the host field of the given PSCSI.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} (host ref) get_host (session_id s, PSCSI 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 PSCSI ref } & self & reference to the object \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+host ref
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_physical\_host}
+
+{\bf Overview:} 
+Get the physical\_host field of the given PSCSI.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} int get_physical_host (session_id s, PSCSI 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 PSCSI ref } & self & reference to the object \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+int
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_physical\_channel}
+
+{\bf Overview:} 
+Get the physical\_channel field of the given PSCSI.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} int get_physical_channel (session_id s, PSCSI 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 PSCSI ref } & self & reference to the object \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+int
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_physical\_target}
+
+{\bf Overview:} 
+Get the physical\_target field of the given PSCSI.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} int get_physical_target (session_id s, PSCSI 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 PSCSI ref } & self & reference to the object \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+int
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_physical\_lun}
+
+{\bf Overview:} 
+Get the physical\_lun field of the given PSCSI.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} int get_physical_lun (session_id s, PSCSI 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 PSCSI ref } & self & reference to the object \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+int
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_physical\_HCTL}
+
+{\bf Overview:} 
+Get the physical\_HCTL field of the given PSCSI.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} string get_physical_HCTL (session_id s, PSCSI 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 PSCSI 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\_vendor\_name}
+
+{\bf Overview:} 
+Get the vendor\_name field of the given PSCSI.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} string get_vendor_name (session_id s, PSCSI 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 PSCSI 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\_model}
+
+{\bf Overview:} 
+Get the model field of the given PSCSI.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} string get_model (session_id s, PSCSI 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 PSCSI 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\_type\_id}
+
+{\bf Overview:} 
+Get the type\_id field of the given PSCSI.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} int get_type_id (session_id s, PSCSI 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 PSCSI ref } & self & reference to the object \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+int
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_type}
+
+{\bf Overview:} 
+Get the type field of the given PSCSI.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} string get_type (session_id s, PSCSI 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 PSCSI 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\_dev\_name}
+
+{\bf Overview:} 
+Get the dev\_name field of the given PSCSI.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} string get_dev_name (session_id s, PSCSI 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 PSCSI 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\_sg\_name}
+
+{\bf Overview:} 
+Get the sg\_name field of the given PSCSI.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} string get_sg_name (session_id s, PSCSI 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 PSCSI 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\_revision}
+
+{\bf Overview:} 
+Get the revision field of the given PSCSI.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} string get_revision (session_id s, PSCSI 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 PSCSI 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\_scsi\_id}
+
+{\bf Overview:} 
+Get the scsi\_id field of the given PSCSI.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} string get_scsi_id (session_id s, PSCSI 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 PSCSI 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\_scsi\_level}
+
+{\bf Overview:} 
+Get the scsi\_level field of the given PSCSI.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} int get_scsi_level (session_id s, PSCSI 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 PSCSI ref } & self & reference to the object \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+int
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_by\_uuid}
+
+{\bf Overview:} 
+Get a reference to the PSCSI instance with the specified UUID.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} (PSCSI ref) get_by_uuid (session_id s, string 
uuid)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt string } & uuid & UUID of object to return \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+PSCSI ref
+}
+
+
+reference to the object
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_record}
+
+{\bf Overview:} 
+Get a record containing the current state of the given PSCSI.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} (PSCSI record) get_record (session_id s, PSCSI 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 PSCSI ref } & self & reference to the object \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+PSCSI record
+}
+
+
+all fields from the object
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+
+\vspace{1cm}
+\newpage
 \section{Class: user}
 \subsection{Fields for class: user}
 \begin{longtable}{|lllp{0.38\textwidth}|}
diff -r 6583186e5989 -r 46d7e12c4c91 tools/blktap/drivers/block-qcow.c
--- a/tools/blktap/drivers/block-qcow.c Wed Oct 22 11:38:22 2008 +0900
+++ b/tools/blktap/drivers/block-qcow.c Wed Oct 22 11:46:55 2008 +0900
@@ -734,8 +734,8 @@ static int tdqcow_open (struct disk_driv
 
        DPRINTF("QCOW: Opening %s\n",name);
 
-       o_flags = O_DIRECT | O_LARGEFILE | 
-               ((flags == TD_RDONLY) ? O_RDONLY : O_RDWR);
+       /* Since we don't handle O_DIRECT correctly, don't use it */
+       o_flags = O_LARGEFILE | ((flags == TD_RDONLY) ? O_RDONLY : O_RDWR);
        fd = open(name, o_flags);
        if (fd < 0) {
                DPRINTF("Unable to open %s (%d)\n",name,0 - errno);
@@ -1385,7 +1385,7 @@ static int tdqcow_get_parent_id(struct d
        filename[len]  = '\0';
 
        id->name       = strdup(filename);
-       id->drivertype = DISK_TYPE_QCOW;
+       id->drivertype = DISK_TYPE_AIO;
        err            = 0;
  out:
        free(buf);
@@ -1397,17 +1397,15 @@ static int tdqcow_validate_parent(struct
 {
        struct stat stats;
        uint64_t psize, csize;
-       struct tdqcow_state *c = (struct tdqcow_state *)child->private;
-       struct tdqcow_state *p = (struct tdqcow_state *)parent->private;
-       
-       if (stat(p->name, &stats))
+       
+       if (stat(parent->name, &stats))
                return -EINVAL;
-       if (get_filesize(p->name, &psize, &stats))
+       if (get_filesize(parent->name, &psize, &stats))
                return -EINVAL;
 
-       if (stat(c->name, &stats))
+       if (stat(child->name, &stats))
                return -EINVAL;
-       if (get_filesize(c->name, &csize, &stats))
+       if (get_filesize(child->name, &csize, &stats))
                return -EINVAL;
 
        if (csize != psize)
diff -r 6583186e5989 -r 46d7e12c4c91 tools/blktap/drivers/block-qcow2.c
--- a/tools/blktap/drivers/block-qcow2.c        Wed Oct 22 11:38:22 2008 +0900
+++ b/tools/blktap/drivers/block-qcow2.c        Wed Oct 22 11:46:55 2008 +0900
@@ -34,6 +34,7 @@
 #include "tapdisk.h"
 #include "tapaio.h"
 #include "bswap.h"
+#include "blk.h"
 
 #define USE_AIO
 
@@ -1902,6 +1903,42 @@ repeat:
 
 #endif 
 
+static int get_filesize(char *filename, uint64_t *size, struct stat *st)
+{
+       int fd;
+       QCowHeader header;
+
+       /*Set to the backing file size*/
+       fd = open(filename, O_RDONLY);
+       if (fd < 0)
+               return -1;
+       if (read(fd, &header, sizeof(header)) < sizeof(header)) {
+               close(fd);
+               return -1;
+       }
+       close(fd);
+       
+       be32_to_cpus(&header.magic);
+       be32_to_cpus(&header.version);
+       be64_to_cpus(&header.size);
+       if (header.magic == QCOW_MAGIC && header.version == QCOW_VERSION) {
+               *size = header.size >> SECTOR_SHIFT;
+               return 0;
+       }
+
+       if(S_ISBLK(st->st_mode)) {
+               fd = open(filename, O_RDONLY);
+               if (fd < 0)
+                       return -1;
+               if (blk_getimagesize(fd, size) != 0) {
+                       close(fd);
+                       return -1;
+               }
+               close(fd);
+       } else *size = (st->st_size >> SECTOR_SHIFT);   
+       return 0;
+}
+
 /**
  * @return 
  *        0 if parent id successfully retrieved;
@@ -1916,7 +1953,7 @@ static int qcow_get_parent_id(struct dis
                return TD_NO_PARENT;
 
        id->name = strdup(s->backing_file);
-       id->drivertype = DISK_TYPE_QCOW2;
+       id->drivertype = DISK_TYPE_AIO;
 
        return 0;
 }
@@ -1924,15 +1961,22 @@ static int qcow_validate_parent(struct d
 static int qcow_validate_parent(struct disk_driver *child, 
                struct disk_driver *parent, td_flag_t flags)
 {
-       struct BDRVQcowState *cs = (struct BDRVQcowState*) child->private;
-       struct BDRVQcowState *ps = (struct BDRVQcowState*) parent->private;
-
-       if (ps->total_sectors != cs->total_sectors) {
-               DPRINTF("qcow_validate_parent(): %#"PRIx64" != %#"PRIx64"\n",
-                       ps->total_sectors, cs->total_sectors);
+       struct stat stats;
+       uint64_t psize, csize;
+       
+       if (stat(parent->name, &stats))
                return -EINVAL;
-       }
-       
+       if (get_filesize(parent->name, &psize, &stats))
+               return -EINVAL;
+
+       if (stat(child->name, &stats))
+               return -EINVAL;
+       if (get_filesize(child->name, &csize, &stats))
+               return -EINVAL;
+
+       if (csize != psize)
+               return -EINVAL;
+
        return 0;
 }
 
diff -r 6583186e5989 -r 46d7e12c4c91 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c   Wed Oct 22 11:38:22 2008 +0900
+++ b/tools/libxc/xc_domain.c   Wed Oct 22 11:46:55 2008 +0900
@@ -1049,6 +1049,18 @@ int xc_domain_get_machine_address_size(i
     return rc == 0 ? domctl.u.address_size.size : rc;
 }
 
+int xc_domain_suppress_spurious_page_faults(int xc, uint32_t domid)
+{
+    DECLARE_DOMCTL;
+
+    memset(&domctl, 0, sizeof(domctl));
+    domctl.domain = domid;
+    domctl.cmd    = XEN_DOMCTL_suppress_spurious_page_faults;
+
+    return do_domctl(xc, &domctl);
+
+}
+
 /*
  * Local variables:
  * mode: C
diff -r 6583186e5989 -r 46d7e12c4c91 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Wed Oct 22 11:38:22 2008 +0900
+++ b/tools/libxc/xenctrl.h     Wed Oct 22 11:46:55 2008 +0900
@@ -1103,6 +1103,9 @@ int xc_domain_get_machine_address_size(i
 int xc_domain_get_machine_address_size(int handle,
                                       uint32_t domid);
 
+int xc_domain_suppress_spurious_page_faults(int handle,
+                                         uint32_t domid);
+
 /* Set the target domain */
 int xc_domain_set_target(int xc_handle,
                          uint32_t domid,
diff -r 6583186e5989 -r 46d7e12c4c91 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Wed Oct 22 11:38:22 2008 +0900
+++ b/tools/python/xen/lowlevel/xc/xc.c Wed Oct 22 11:46:55 2008 +0900
@@ -859,6 +859,21 @@ static PyObject *pyxc_dom_set_machine_ad
     return zero;
 }
 
+static PyObject *pyxc_dom_suppress_spurious_page_faults(XcObject *self,
+                                                     PyObject *args,
+                                                     PyObject *kwds)
+{
+    uint32_t dom;
+
+    if (!PyArg_ParseTuple(args, "i", &dom))
+       return NULL;
+
+    if (xc_domain_suppress_spurious_page_faults(self->xc_handle, dom) != 0)
+       return pyxc_error_to_exception();
+
+    Py_INCREF(zero);
+    return zero;
+}
 #endif /* __i386__ || __x86_64__ */
 
 static PyObject *pyxc_hvm_build(XcObject *self,
@@ -1911,6 +1926,12 @@ static PyMethodDef pyxc_methods[] = {
       "Set maximum machine address size for this domain.\n"
       " dom [int]: Identifier of domain.\n"
       " width [int]: Maximum machine address width.\n" },
+
+    { "domain_suppress_spurious_page_faults",
+      (PyCFunction)pyxc_dom_suppress_spurious_page_faults,
+      METH_VARARGS, "\n"
+      "Do not propagate spurious page faults to this guest.\n"
+      " dom [int]: Identifier of domain.\n" },
 #endif
 
     { NULL, NULL, 0, NULL }
diff -r 6583186e5989 -r 46d7e12c4c91 tools/python/xen/util/pci.py
--- a/tools/python/xen/util/pci.py      Wed Oct 22 11:38:22 2008 +0900
+++ b/tools/python/xen/util/pci.py      Wed Oct 22 11:46:55 2008 +0900
@@ -12,8 +12,8 @@ import types
 import types
 import struct
 import time
-
-PROC_MNT_PATH = '/proc/mounts'
+from xen.util import utils
+
 PROC_PCI_PATH = '/proc/bus/pci/devices'
 PROC_PCI_NUM_RESOURCES = 7
 
@@ -97,9 +97,6 @@ MSIX_SIZE_MASK = 0x7ff
 # Global variable to store information from lspci
 lspci_info = None
 
-# Global variable to store the sysfs mount point
-sysfs_mnt_point = None
-
 #Calculate PAGE_SHIFT: number of bits to shift an address to get the page 
number
 PAGE_SIZE = resource.getpagesize()
 PAGE_SHIFT = 0
@@ -141,20 +138,8 @@ def parse_pci_name(pci_name_string):
  
 
 def find_sysfs_mnt():
-    global sysfs_mnt_point
-    if not sysfs_mnt_point is None:
-        return sysfs_mnt_point
-
     try:
-        mounts_file = open(PROC_MNT_PATH,'r')
-
-        for line in mounts_file:
-            sline = line.split()
-            if len(sline)<3:
-                continue
-            if sline[2]=='sysfs':
-                sysfs_mnt_point= sline[1]
-                return sysfs_mnt_point
+        return utils.find_sysfs_mount()
     except IOError, (errno, strerr):
         raise PciDeviceParseError(('Failed to locate sysfs mount: %s: %s (%d)'%
             (PROC_PCI_PATH, strerr, errno)))
diff -r 6583186e5989 -r 46d7e12c4c91 tools/python/xen/util/utils.py
--- a/tools/python/xen/util/utils.py    Wed Oct 22 11:38:22 2008 +0900
+++ b/tools/python/xen/util/utils.py    Wed Oct 22 11:46:55 2008 +0900
@@ -48,3 +48,29 @@ def daemonize(prog, args, stdin_tmpfile=
     os.waitpid(pid, 0)
     return daemon_pid
 
+# Global variable to store the sysfs mount point
+sysfs_mount_point = None
+
+PROC_MOUNTS_PATH = '/proc/mounts'
+
+def find_sysfs_mount():
+    global sysfs_mount_point
+
+    if not sysfs_mount_point is None:
+        return sysfs_mount_point
+
+    try:
+        mounts_file = open(PROC_MOUNTS_PATH, 'r')
+
+        for line in mounts_file:
+            sline = line.split()
+            if len(sline) < 3:
+                continue
+            if sline[2] == 'sysfs':
+                sysfs_mount_point= sline[1]
+                return sysfs_mount_point
+    except IOError, (errno, strerr):
+        raise
+
+    return None
+
diff -r 6583186e5989 -r 46d7e12c4c91 tools/python/xen/util/vscsi_util.py
--- a/tools/python/xen/util/vscsi_util.py       Wed Oct 22 11:38:22 2008 +0900
+++ b/tools/python/xen/util/vscsi_util.py       Wed Oct 22 11:46:55 2008 +0900
@@ -23,32 +23,40 @@
 """Support for VSCSI Devices.
 """
 import os
+import os.path
 import sys
 import re
 import string
-
-def _vscsi_hctl_block(name, scsi_devices):
-    """ block-device name is convert into hctl. (e.g., '/dev/sda',
-    '0:0:0:0')"""
+from xen.util import utils
+
+SYSFS_SCSI_PATH = "/bus/scsi/devices"
+SYSFS_SCSI_DEV_VENDOR_PATH = '/vendor'
+SYSFS_SCSI_DEV_MODEL_PATH = '/model'
+SYSFS_SCSI_DEV_TYPEID_PATH = '/type'
+SYSFS_SCSI_DEV_REVISION_PATH = '/rev'
+SYSFS_SCSI_DEV_SCSILEVEL_PATH = '/scsi_level'
+
+def _vscsi_get_devname_by(name, scsi_devices):
+    """A device name is gotten by the HCTL.
+    (e.g., '0:0:0:0' to '/dev/sda')
+    """
+
     try:
         search = re.compile(r'' + name + '$', re.DOTALL)
     except Exception, e:
         raise VmError("vscsi: invalid expression. " + str(e))
-    chk = 0
-    for hctl, block, sg, scsi_id in scsi_devices:
+
+    for hctl, devname, sg, scsi_id in scsi_devices:
         if search.match(hctl):
-            chk = 1
-            break
-
-    if chk:
-        return (hctl, block)
-    else:
-        return (None, None)
-
-
-def _vscsi_block_scsiid_to_hctl(phyname, scsi_devices):
-    """ block-device name is convert into hctl. (e.g., '/dev/sda',
-    '0:0:0:0')"""
+            return (hctl, devname)
+
+    return (None, None)
+
+
+def _vscsi_get_hctl_by(phyname, scsi_devices):
+    """An HCTL is gotten by the device name or the scsi_id.
+    (e.g., '/dev/sda' to '0:0:0:0')
+    """
     
     if re.match('/dev/sd[a-z]+([1-9]|1[0-5])?$', phyname):
         # sd driver
@@ -63,71 +71,148 @@ def _vscsi_block_scsiid_to_hctl(phyname,
         # scsi_id -gu
         name = phyname
 
-    chk = 0
-    for hctl, block, sg, scsi_id in scsi_devices:
-        if block == name:
-            chk = 1
-            break
-        elif sg == name:
-            chk = 1
-            break
-        elif scsi_id == name:
-            chk = 1
-            break
-
-    if chk:
-        return (hctl, block)
-    else:
-        return (None, None)
+    for hctl, devname, sg, scsi_id in scsi_devices:
+        if name in [devname, sg, scsi_id]:
+            return (hctl, devname)
+
+    return (None, None)
 
 
 def vscsi_get_scsidevices():
     """ get all scsi devices"""
 
-    SERCH_SCSI_PATH = "/sys/bus/scsi/devices"
     devices = []
-
-    for dirpath, dirnames, files in os.walk(SERCH_SCSI_PATH):
+    sysfs_mnt = utils.find_sysfs_mount() 
+
+    for dirpath, dirnames, files in os.walk(sysfs_mnt + SYSFS_SCSI_PATH):
         for hctl in dirnames:
             paths = os.path.join(dirpath, hctl)
-            block = "-"
+            devname = None
+            sg = None
+            scsi_id = None
             for f in os.listdir(paths):
-                if re.match('^block', f):
-                    os.chdir(os.path.join(paths, f))
-                    block = os.path.basename(os.getcwd())
-                elif re.match('^tape', f):
-                    os.chdir(os.path.join(paths, f))
-                    block = os.path.basename(os.getcwd())
-                elif re.match('^scsi_changer', f):
-                    os.chdir(os.path.join(paths, f))
-                    block = os.path.basename(os.getcwd())
-                elif re.match('^onstream_tape', f):
-                    os.chdir(os.path.join(paths, f))
-                    block = os.path.basename(os.getcwd())
+                realpath = os.path.realpath(os.path.join(paths, f))
+                if  re.match('^block', f) or \
+                    re.match('^tape', f) or \
+                    re.match('^scsi_changer', f) or \
+                    re.match('^onstream_tape', f):
+                    devname = os.path.basename(realpath)
 
                 if re.match('^scsi_generic', f):
-                    os.chdir(os.path.join(paths, f))
-                    sg = os.path.basename(os.getcwd())
+                    sg = os.path.basename(realpath)
                     lines = os.popen('/sbin/scsi_id -gu -s 
/class/scsi_generic/' + sg).read().split()
-                    if len(lines) == 0:
-                        scsi_id = '-'
-                    else:
+                    if len(lines):
                         scsi_id = lines[0]
 
-            devices.append([hctl, block, sg, scsi_id])
+            devices.append([hctl, devname, sg, scsi_id])
 
     return devices
 
 
-def vscsi_search_hctl_and_block(device):
-
-    scsi_devices = vscsi_get_scsidevices()
-
-    tmp = device.split(':')
-    if len(tmp) == 4:
-        (hctl, block) = _vscsi_hctl_block(device, scsi_devices)
+def vscsi_get_hctl_and_devname_by(target, scsi_devices = None):
+    if scsi_devices is None:
+        scsi_devices = vscsi_get_scsidevices()
+
+    if len(target.split(':')) == 4:
+        return _vscsi_get_devname_by(target, scsi_devices)
     else:
-        (hctl, block) = _vscsi_block_scsiid_to_hctl(device, scsi_devices)
-
-    return (hctl, block)
-
+        return _vscsi_get_hctl_by(target, scsi_devices)
+
+
+def get_scsi_vendor(pHCTL):
+    try:
+        sysfs_mnt = utils.find_sysfs_mount() 
+        sysfs_scsi_dev_path = \
+            os.path.join(sysfs_mnt + SYSFS_SCSI_PATH, pHCTL)
+        scsi_vendor = \
+            os.popen('cat ' + sysfs_scsi_dev_path + \
+                              SYSFS_SCSI_DEV_VENDOR_PATH).read()
+        return scsi_vendor.splitlines()[0]
+    except:
+        return None
+
+def get_scsi_model(pHCTL):
+    try:
+        sysfs_mnt = utils.find_sysfs_mount() 
+        sysfs_scsi_dev_path = \
+            os.path.join(sysfs_mnt + SYSFS_SCSI_PATH, pHCTL)
+        scsi_model = \
+            os.popen('cat ' + sysfs_scsi_dev_path + \
+                              SYSFS_SCSI_DEV_MODEL_PATH).read()
+        return scsi_model.splitlines()[0]
+    except:
+        return None
+
+def get_scsi_typeid(pHCTL):
+    try:
+        sysfs_mnt = utils.find_sysfs_mount() 
+        sysfs_scsi_dev_path = \
+            os.path.join(sysfs_mnt + SYSFS_SCSI_PATH, pHCTL)
+        scsi_typeid = \
+            os.popen('cat ' + sysfs_scsi_dev_path + \
+                              SYSFS_SCSI_DEV_TYPEID_PATH).read()
+        return int(scsi_typeid.splitlines()[0])
+    except:
+        return None
+
+def get_scsi_revision(pHCTL):
+    try:
+        sysfs_mnt = utils.find_sysfs_mount() 
+        sysfs_scsi_dev_path = \
+            os.path.join(sysfs_mnt + SYSFS_SCSI_PATH, pHCTL)
+        scsi_revision = \
+            os.popen('cat ' + sysfs_scsi_dev_path + \
+                              SYSFS_SCSI_DEV_REVISION_PATH).read()
+        return scsi_revision.splitlines()[0]
+    except:
+        return None
+
+def get_scsi_scsilevel(pHCTL):
+    try:
+        sysfs_mnt = utils.find_sysfs_mount() 
+        sysfs_scsi_dev_path = \
+            os.path.join(sysfs_mnt + SYSFS_SCSI_PATH, pHCTL)
+        scsi_scsilevel = \
+            os.popen('cat ' + sysfs_scsi_dev_path + \
+                              SYSFS_SCSI_DEV_SCSILEVEL_PATH).read()
+        return int(scsi_scsilevel.splitlines()[0])
+    except:
+        return None
+
+def get_all_scsi_devices():
+
+    scsi_devs = []
+
+    for scsi_info in vscsi_get_scsidevices():
+        scsi_dev = {
+            'physical_HCTL': scsi_info[0],
+            'dev_name': None,
+            'sg_name': scsi_info[2],
+            'scsi_id': None
+        }
+        if scsi_info[1] is not None:
+            scsi_dev['dev_name'] = scsi_info[1] 
+        if scsi_info[3] is not None:
+            scsi_dev['scsi_id'] = scsi_info[3] 
+
+        scsi_dev['vendor_name'] = \
+            get_scsi_vendor(scsi_dev['physical_HCTL'])
+        scsi_dev['model'] = \
+            get_scsi_model(scsi_dev['physical_HCTL'])
+        scsi_dev['type_id'] = \
+            get_scsi_typeid(scsi_dev['physical_HCTL'])
+        scsi_dev['revision'] = \
+            get_scsi_revision(scsi_dev['physical_HCTL'])
+        scsi_dev['scsi_level'] = \
+            get_scsi_scsilevel(scsi_dev['physical_HCTL'])
+
+        try:
+            lsscsi_info = os.popen('lsscsi ' + 
scsi_dev['physical_HCTL']).read().split()
+            scsi_dev['type'] = lsscsi_info[1]
+        except:
+            scsi_dev['type'] = None
+
+        scsi_devs.append(scsi_dev)
+
+    return scsi_devs
+
diff -r 6583186e5989 -r 46d7e12c4c91 tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py  Wed Oct 22 11:38:22 2008 +0900
+++ b/tools/python/xen/xend/XendAPI.py  Wed Oct 22 11:46:55 2008 +0900
@@ -42,6 +42,8 @@ from XendPBD import XendPBD
 from XendPBD import XendPBD
 from XendPPCI import XendPPCI
 from XendDPCI import XendDPCI
+from XendPSCSI import XendPSCSI
+from XendDSCSI import XendDSCSI
 from XendXSPolicy import XendXSPolicy, XendACMPolicy
 
 from XendAPIConstants import *
@@ -480,7 +482,9 @@ classes = {
     'PBD'          : valid_object("PBD"),
     'PIF_metrics'  : valid_object("PIF_metrics"),
     'PPCI'         : valid_object("PPCI"),
-    'DPCI'         : valid_object("DPCI")
+    'DPCI'         : valid_object("DPCI"),
+    'PSCSI'        : valid_object("PSCSI"),
+    'DSCSI'        : valid_object("DSCSI")
 }
 
 autoplug_classes = {
@@ -491,6 +495,8 @@ autoplug_classes = {
     'PIF_metrics' : XendPIFMetrics,
     'PPCI'        : XendPPCI,
     'DPCI'        : XendDPCI,
+    'PSCSI'       : XendPSCSI,
+    'DSCSI'       : XendDSCSI,
     'XSPolicy'    : XendXSPolicy,
     'ACMPolicy'   : XendACMPolicy,
 }
@@ -881,6 +887,7 @@ class XendAPI(object):
                     'PBDs',
                     'PIFs',
                     'PPCIs',
+                    'PSCSIs',
                     'host_CPUs',
                     'cpu_configuration',
                     'metrics',
@@ -961,6 +968,8 @@ class XendAPI(object):
         return xen_api_success(XendNode.instance().get_PIF_refs())
     def host_get_PPCIs(self, session, ref):
         return xen_api_success(XendNode.instance().get_PPCI_refs())
+    def host_get_PSCSIs(self, session, ref):
+        return xen_api_success(XendNode.instance().get_PSCSI_refs())
     def host_get_host_CPUs(self, session, host_ref):
         return xen_api_success(XendNode.instance().get_host_cpu_refs())
     def host_get_metrics(self, _, ref):
@@ -1037,7 +1046,8 @@ class XendAPI(object):
                   'logging': {},
                   'PIFs': XendPIF.get_all(),
                   'PBDs': XendPBD.get_all(),
-                  'PPCIs': XendPPCI.get_all()}
+                  'PPCIs': XendPPCI.get_all(),
+                  'PSCSIs': XendPSCSI.get_all()}
         return xen_api_success(record)
 
     # class methods
@@ -1158,6 +1168,7 @@ class XendAPI(object):
                   'VBDs',
                   'VTPMs',
                   'DPCIs',
+                  'DSCSIs',
                   'tools_version',
                   'domid',
                   'is_control_domain',
@@ -1304,6 +1315,10 @@ class XendAPI(object):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return xen_api_success(dom.get_dpcis())
     
+    def VM_get_DSCSIs(self, session, vm_ref):
+        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+        return xen_api_success(dom.get_dscsis())
+
     def VM_get_tools_version(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
         return dom.get_tools_version()
@@ -1684,6 +1699,7 @@ class XendAPI(object):
             'VBDs': xeninfo.get_vbds(),
             'VTPMs': xeninfo.get_vtpms(),
             'DPCIs': xeninfo.get_dpcis(),
+            'DSCSIs': xeninfo.get_dscsis(),
             'PV_bootloader': xeninfo.info.get('PV_bootloader'),
             'PV_kernel': xeninfo.info.get('PV_kernel'),
             'PV_ramdisk': xeninfo.info.get('PV_ramdisk'),
diff -r 6583186e5989 -r 46d7e12c4c91 tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Wed Oct 22 11:38:22 2008 +0900
+++ b/tools/python/xen/xend/XendConfig.py       Wed Oct 22 11:46:55 2008 +0900
@@ -26,6 +26,8 @@ from xen.xend import XendAPIStore
 from xen.xend import XendAPIStore
 from xen.xend.XendPPCI import XendPPCI
 from xen.xend.XendDPCI import XendDPCI
+from xen.xend.XendPSCSI import XendPSCSI
+from xen.xend.XendDSCSI import XendDSCSI
 from xen.xend.XendError import VmError
 from xen.xend.XendDevices import XendDevices
 from xen.xend.PrettyPrint import prettyprintstring
@@ -210,6 +212,7 @@ XENAPI_CFG_TYPES = {
     'cpuid' : dict,
     'cpuid_check' : dict,
     'machine_address_size': int,
+    'suppress_spurious_page_faults': bool0,
 }
 
 # List of legacy configuration keys that have no equivalent in the
@@ -781,8 +784,8 @@ class XendConfig(dict):
         log.debug('_sxp_to_xapi(%s)' % scrub_password(sxp_cfg))
 
         # _parse_sxp() below will call device_add() and construct devices.
-        # Some devices (currently only pci) may require VM's uuid, so
-        # setup self['uuid'] beforehand.
+        # Some devices may require VM's uuid, so setup self['uuid']
+        # beforehand.
         self['uuid'] = sxp.child_value(sxp_cfg, 'uuid', uuid.createString())
 
         cfg = self._parse_sxp(sxp_cfg)
@@ -1221,29 +1224,28 @@ class XendConfig(dict):
             dev_type = sxp.name(config)
             dev_info = {}
 
-            if dev_type == 'pci' or dev_type == 'vscsi':
+            if dev_type == 'pci':
                 pci_devs_uuid = sxp.child_value(config, 'uuid',
                                                 uuid.createString())
 
                 pci_dict = self.pci_convert_sxp_to_dict(config)
                 pci_devs = pci_dict['devs']
 
-                if dev_type != 'vscsi':
-                    # create XenAPI DPCI objects.
-                    for pci_dev in pci_devs:
-                        dpci_uuid = pci_dev.get('uuid')
-                        ppci_uuid = XendPPCI.get_by_sbdf(pci_dev['domain'],
-                                                        pci_dev['bus'],
-                                                        pci_dev['slot'],
-                                                        pci_dev['func'])
-                        if ppci_uuid is None:
-                            continue
-                        dpci_record = {
-                            'VM': self['uuid'],
-                            'PPCI': ppci_uuid,
-                            'hotplug_slot': pci_dev.get('vslot', 0)
-                        }
-                        XendDPCI(dpci_uuid, dpci_record)
+                # create XenAPI DPCI objects.
+                for pci_dev in pci_devs:
+                    dpci_uuid = pci_dev.get('uuid')
+                    ppci_uuid = XendPPCI.get_by_sbdf(pci_dev['domain'],
+                                                     pci_dev['bus'],
+                                                     pci_dev['slot'],
+                                                     pci_dev['func'])
+                    if ppci_uuid is None:
+                        continue
+                    dpci_record = {
+                        'VM': self['uuid'],
+                        'PPCI': ppci_uuid,
+                        'hotplug_slot': pci_dev.get('vslot', 0)
+                    }
+                    XendDPCI(dpci_uuid, dpci_record)
 
                 target['devices'][pci_devs_uuid] = (dev_type,
                                                     {'devs': pci_devs,
@@ -1252,6 +1254,30 @@ class XendConfig(dict):
                 log.debug("XendConfig: reading device: %s" % pci_devs)
 
                 return pci_devs_uuid
+
+            if dev_type == 'vscsi':
+                vscsi_devs_uuid = sxp.child_value(config, 'uuid',
+                                                  uuid.createString())
+                vscsi_dict = self.vscsi_convert_sxp_to_dict(config)
+                vscsi_devs = vscsi_dict['devs']
+
+                # create XenAPI DSCSI objects.
+                for vscsi_dev in vscsi_devs:
+                    dscsi_uuid = vscsi_dev.get('uuid')
+                    pscsi_uuid = XendPSCSI.get_by_HCTL(vscsi_dev['p-dev'])
+                    if pscsi_uuid is None:
+                        continue
+                    dscsi_record = {
+                        'VM': self['uuid'],
+                        'PSCSI': pscsi_uuid,
+                        'virtual_HCTL': vscsi_dev.get('v-dev')
+                    }
+                    XendDSCSI(dscsi_uuid, dscsi_record)
+
+                target['devices'][vscsi_devs_uuid] = \
+                    (dev_type, {'devs': vscsi_devs, 'uuid': vscsi_devs_uuid} )
+                log.debug("XendConfig: reading device: %s" % vscsi_devs)
+                return vscsi_devs_uuid
 
             for opt_val in config[1:]:
                 try:
@@ -1558,6 +1584,86 @@ class XendConfig(dict):
 
         return dev_config
 
+    def vscsi_convert_sxp_to_dict(self, dev_sxp):
+        """Convert vscsi device sxp to dict
+        @param dev_sxp: device configuration
+        @type  dev_sxp: SXP object (parsed config)
+        @return: dev_config
+        @rtype: dictionary
+        """
+        # Parsing the device SXP's. In most cases, the SXP looks
+        # like this:
+        #
+        # [device, [vif, [mac, xx:xx:xx:xx:xx:xx], [ip 1.3.4.5]]]
+        #
+        # However, for SCSI devices it looks like this:
+        #
+        # [device,
+        #   [vscsi,
+        #     [dev,
+        #       [devid, 0], [p-devname, sdb], [p-dev, 1:0:0:1],
+        #       [v-dev, 0:0:0:0], [state, Initialising]
+        #     ],
+        #     [dev,
+        #       [devid, 0], [p-devname, sdc], [p-dev, 1:0:0:2],
+        #       [v-dev, 0:0:0:1], [satet, Initialising]
+        #     ]
+        #   ],
+        #   [vscsi,
+        #     [dev,
+        #       [devid, 1], [p-devname, sdg], [p-dev, 2:0:0:0],
+        #       [v-dev, 1:0:0:0], [state, Initialising]
+        #     ],
+        #     [dev,
+        #       [devid, 1], [p-devname, sdh], [p-dev, 2:0:0:1],
+        #       [v-dev, 1:0:0:1], [satet, Initialising]
+        #     ]
+        #   ]
+        # ]
+        #
+        # It seems the reasoning for this difference is because
+        # vscsiif.py needs all the SCSI device configurations with 
+        # same host number at the same time when creating the devices.
+
+        # For SCSI device hotplug support, the SXP of SCSI devices is
+        # extendend like this:
+        #
+        # [device,
+        #   [vscsi,
+        #     [dev,
+        #       [devid, 0], [p-devname, sdd], [p-dev, 1:0:0:3],
+        #       [v-dev, 0:0:0:2], [state, Initialising]
+        #     ]
+        #   ]
+        # ]
+        #
+        # state 'Initialising' indicates that the device is being attached,
+        # while state 'Closing' indicates that the device is being detached.
+        #
+        # The Dict looks like this:
+        #
+        # { devs: [ {devid: 0, p-devname: sdd, p-dev: 1:0:0:3,
+        #            v-dev: 0:0:0:2, state: Initialising} ] }
+
+        dev_config = {}
+
+        vscsi_devs = []
+        for vscsi_dev in sxp.children(dev_sxp, 'dev'):
+            vscsi_dev_info = {}
+            for opt_val in vscsi_dev[1:]:
+                try:
+                    opt, val = opt_val
+                    vscsi_dev_info[opt] = val
+                except TypeError:
+                    pass
+            # append uuid for each vscsi device.
+            vscsi_uuid = vscsi_dev_info.get('uuid', uuid.createString())
+            vscsi_dev_info['uuid'] = vscsi_uuid
+            vscsi_devs.append(vscsi_dev_info)
+        dev_config['devs'] = vscsi_devs 
+
+        return dev_config
+
     def console_add(self, protocol, location, other_config = {}):
         dev_uuid = uuid.createString()
         if protocol == 'vt100':
@@ -1631,7 +1737,7 @@ class XendConfig(dict):
 
             dev_type, dev_info = self['devices'][dev_uuid]
 
-            if dev_type == 'pci' or dev_type == 'vscsi': # Special case for pci
+            if dev_type == 'pci': # Special case for pci
                 pci_dict = self.pci_convert_sxp_to_dict(config)
                 pci_devs = pci_dict['devs']
 
@@ -1639,26 +1745,50 @@ class XendConfig(dict):
                 for dpci_uuid in XendDPCI.get_by_VM(self['uuid']):
                     XendAPIStore.deregister(dpci_uuid, "DPCI")
 
-                if dev_type != 'vscsi':
-                    # create XenAPI DPCI objects.
-                    for pci_dev in pci_devs:
-                        dpci_uuid = pci_dev.get('uuid')
-                        ppci_uuid = XendPPCI.get_by_sbdf(pci_dev['domain'],
-                                                         pci_dev['bus'],
-                                                         pci_dev['slot'],
-                                                         pci_dev['func'])
-                        if ppci_uuid is None:
-                            continue
-                        dpci_record = {
-                            'VM': self['uuid'],
-                            'PPCI': ppci_uuid,
-                            'hotplug_slot': pci_dev.get('vslot', 0)
-                        }
-                        XendDPCI(dpci_uuid, dpci_record)
+                # create XenAPI DPCI objects.
+                for pci_dev in pci_devs:
+                    dpci_uuid = pci_dev.get('uuid')
+                    ppci_uuid = XendPPCI.get_by_sbdf(pci_dev['domain'],
+                                                     pci_dev['bus'],
+                                                     pci_dev['slot'],
+                                                     pci_dev['func'])
+                    if ppci_uuid is None:
+                        continue
+                    dpci_record = {
+                        'VM': self['uuid'],
+                        'PPCI': ppci_uuid,
+                        'hotplug_slot': pci_dev.get('vslot', 0)
+                    }
+                    XendDPCI(dpci_uuid, dpci_record)
 
                 self['devices'][dev_uuid] = (dev_type,
                                              {'devs': pci_devs,
                                               'uuid': dev_uuid})
+                return True
+                
+            if dev_type == 'vscsi': # Special case for vscsi
+                vscsi_dict = self.vscsi_convert_sxp_to_dict(config)
+                vscsi_devs = vscsi_dict['devs']
+
+                # destroy existing XenAPI DSCSI objects
+                for dscsi_uuid in XendDSCSI.get_by_VM(self['uuid']):
+                    XendAPIStore.deregister(dscsi_uuid, "DSCSI")
+
+                # create XenAPI DSCSI objects.
+                for vscsi_dev in vscsi_devs:
+                    dscsi_uuid = vscsi_dev.get('uuid')
+                    pscsi_uuid = XendPSCSI.get_by_HCTL(vscsi_dev['p-dev'])
+                    if pscsi_uuid is None:
+                        continue
+                    dscsi_record = {
+                        'VM': self['uuid'],
+                        'PSCSI': pscsi_uuid,
+                        'virtual_HCTL': vscsi_dev.get('v-dev')
+                    }
+                    XendDSCSI(dscsi_uuid, dscsi_record)
+
+                self['devices'][dev_uuid] = \
+                    (dev_type, {'devs': vscsi_devs, 'uuid': dev_uuid} )
                 return True
                 
             for opt_val in config[1:]:
diff -r 6583186e5989 -r 46d7e12c4c91 tools/python/xen/xend/XendDSCSI.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xend/XendDSCSI.py        Wed Oct 22 11:46:55 2008 +0900
@@ -0,0 +1,174 @@
+#============================================================================
+# 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 FUJITSU LIMITED 2008
+#       Masaki Kanno <kanno.masaki@xxxxxxxxxxxxxx>
+#============================================================================
+
+from xen.xend.XendBase import XendBase
+from xen.xend.XendPSCSI import XendPSCSI
+from xen.xend import XendAPIStore
+from xen.xend import sxp
+from xen.xend import uuid as genuuid
+
+import XendDomain, XendNode
+
+from XendError import *
+from XendTask import XendTask
+from XendLogging import log
+
+class XendDSCSI(XendBase):
+    """Representation of a half-virtualized SCSI device."""
+
+    def getClass(self):
+        return "DSCSI"
+
+    def getAttrRO(self):
+        attrRO = ['VM',
+                  'PSCSI',
+                  'virtual_host',
+                  'virtual_channel',
+                  'virtual_target',
+                  'virtual_lun',
+                  'virtual_HCTL',
+                  'runtime_properties']
+        return XendBase.getAttrRO() + attrRO
+
+    def getAttrRW(self):
+        attrRW = []
+        return XendBase.getAttrRW() + attrRW
+
+    def getAttrInst(self):
+        attrInst = ['VM',
+                    'PSCSI',
+                    'virtual_HCTL']
+        return XendBase.getAttrInst() + attrInst
+
+    def getMethods(self):
+        methods = ['destroy']
+        return XendBase.getMethods() + methods
+
+    def getFuncs(self):
+        funcs = ['create']
+        return XendBase.getFuncs() + funcs
+
+    getClass    = classmethod(getClass)
+    getAttrRO   = classmethod(getAttrRO)
+    getAttrRW   = classmethod(getAttrRW)
+    getAttrInst = classmethod(getAttrInst)
+    getMethods  = classmethod(getMethods)
+    getFuncs    = classmethod(getFuncs)
+ 
+    def create(self, dscsi_struct):
+
+        # Check if VM is valid
+        xendom = XendDomain.instance()
+        if not xendom.is_valid_vm(dscsi_struct['VM']):
+            raise InvalidHandleError('VM', dscsi_struct['VM'])
+        dom = xendom.get_vm_by_uuid(dscsi_struct['VM'])
+
+        # Check if PSCSI is valid
+        xennode = XendNode.instance()
+        pscsi_uuid = xennode.get_pscsi_by_uuid(dscsi_struct['PSCSI'])
+        if not pscsi_uuid:
+            raise InvalidHandleError('PSCSI', dscsi_struct['PSCSI'])
+
+        # Assign PSCSI to VM
+        try:
+            dscsi_ref = XendTask.log_progress(0, 100, \
+                                              dom.create_dscsi, \
+                                              dscsi_struct)
+        except XendError, e:
+            log.exception("Error in create_dscsi")
+            raise
+
+        return dscsi_ref
+
+    create = classmethod(create)
+
+    def get_by_VM(cls, VM_ref):
+        result = []
+        for dscsi in XendAPIStore.get_all("DSCSI"):
+            if dscsi.get_VM() == VM_ref:
+                result.append(dscsi.get_uuid())
+        return result
+
+    get_by_VM = classmethod(get_by_VM)
+
+    def __init__(self, uuid, record):
+        XendBase.__init__(self, uuid, record)
+        v_hctl = self.virtual_HCTL.split(':')
+        self.virtual_host = int(v_hctl[0])
+        self.virtual_channel = int(v_hctl[1])
+        self.virtual_target = int(v_hctl[2])
+        self.virtual_lun = int(v_hctl[3])
+
+    def get_VM(self):
+        return self.VM
+
+    def get_PSCSI(self):
+        return self.PSCSI
+
+    def get_virtual_host(self):
+        return self.virtual_host
+
+    def get_virtual_channel(self):
+        return self.virtual_channel
+
+    def get_virtual_target(self):
+        return self.virtual_target
+
+    def get_virtual_lun(self):
+        return self.virtual_lun
+
+    def get_virtual_HCTL(self):
+        return self.virtual_HCTL
+
+    def get_runtime_properties(self):
+        xendom = XendDomain.instance()
+        dominfo = xendom.get_vm_by_uuid(self.VM)
+
+        try:
+            device_dict = {}
+            for device_sxp in dominfo.getDeviceSxprs('vscsi'):
+                target_dev = None
+                for dev in device_sxp[1][0][1]:
+                    vdev = sxp.child_value(dev, 'v-dev')
+                    if vdev == self.virtual_HCTL:
+                        target_dev = dev
+                        break
+                if target_dev is None:
+                    continue
+
+                dev_dict = {}
+                for info in target_dev[1:]:
+                    dev_dict[info[0]] = info[1]
+                device_dict['dev'] = dev_dict
+                for info in device_sxp[1][1:]:
+                    device_dict[info[0]] = info[1]
+
+            return device_dict
+        except Exception, exn:
+            log.exception(exn)
+            return {}
+
+    def destroy(self):
+        xendom = XendDomain.instance()
+        dom = xendom.get_vm_by_uuid(self.get_VM())
+        if not dom:
+            raise InvalidHandleError("VM", self.get_VM())
+        XendTask.log_progress(0, 100, \
+                              dom.destroy_dscsi, \
+                              self.get_uuid())
+
diff -r 6583186e5989 -r 46d7e12c4c91 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Wed Oct 22 11:38:22 2008 +0900
+++ b/tools/python/xen/xend/XendDomainInfo.py   Wed Oct 22 11:46:55 2008 +0900
@@ -55,9 +55,11 @@ from xen.xend.XendAPIConstants import *
 
 from xen.xend.XendVMMetrics import XendVMMetrics
 
+from xen.xend import XendAPIStore
 from xen.xend.XendPPCI import XendPPCI
 from xen.xend.XendDPCI import XendDPCI
-from xen.xend import XendAPIStore
+from xen.xend.XendPSCSI import XendPSCSI
+from xen.xend.XendDSCSI import XendDSCSI
 
 MIGRATE_TIMEOUT = 30.0
 BOOTLOADER_LOOPBACK_DEVICE = '/dev/xvdp'
@@ -663,6 +665,9 @@ class XendDomainInfo:
                 if dev_type == 'pci':
                     for dev in dev_config_dict['devs']:
                         XendAPIStore.deregister(dev['uuid'], 'DPCI')
+                if dev_type == 'vscsi':
+                    for dev in dev_config_dict['devs']:
+                        XendAPIStore.deregister(dev['uuid'], 'DSCSI')
                 elif dev_type == 'tap':
                     self.info['vbd_refs'].remove(dev_uuid)
                 else:
@@ -786,12 +791,11 @@ class XendDomainInfo:
         if dev_class != 'vscsi':
             return False
 
-        dev_config = self.info.pci_convert_sxp_to_dict(dev_sxp)
+        dev_config = self.info.vscsi_convert_sxp_to_dict(dev_sxp)
         dev = dev_config['devs'][0]
-        req_devid = sxp.child_value(dev_sxp, 'devid')
-        req_devid = int(req_devid)
+        req_devid = int(dev['devid'])
         existing_dev_info = self._getDeviceInfo_vscsi(req_devid, dev['v-dev'])
-        state = sxp.child_value(dev_sxp, 'state')
+        state = dev['state']
 
         if state == 'Initialising':
             # new create
@@ -1502,23 +1506,18 @@ class XendDomainInfo:
         return self.info['VCPUs_max']
 
     def setVCpuCount(self, vcpus):
-        if vcpus <= 0:
-            raise XendError('Invalid VCPUs')
+        def vcpus_valid(n):
+            if vcpus <= 0:
+                raise XendError('Zero or less VCPUs is invalid')
+            if self.domid >= 0 and vcpus > self.info['VCPUs_max']:
+                raise XendError('Cannot set vcpus greater than max vcpus on 
running domain')
+        vcpus_valid(vcpus)
         
         self.info['vcpu_avail'] = (1 << vcpus) - 1
         if self.domid >= 0:
             self.storeVm('vcpu_avail', self.info['vcpu_avail'])
-            # update dom differently depending on whether we are adjusting
-            # vcpu number up or down, otherwise _vcpuDomDetails does not
-            # disable the vcpus
-            if self.info['VCPUs_max'] > vcpus:
-                # decreasing
-                self._writeDom(self._vcpuDomDetails())
-                self.info['VCPUs_live'] = vcpus
-            else:
-                # same or increasing
-                self.info['VCPUs_live'] = vcpus
-                self._writeDom(self._vcpuDomDetails())
+            self._writeDom(self._vcpuDomDetails())
+            self.info['VCPUs_live'] = vcpus
         else:
             if self.info['VCPUs_max'] > vcpus:
                 # decreasing
@@ -1528,7 +1527,7 @@ class XendDomainInfo:
                 for c in range(self.info['VCPUs_max'], vcpus):
                     self.info['cpus'].append(list())
             self.info['VCPUs_max'] = vcpus
-            xen.xend.XendDomain.instance().managed_config_save(self)
+        xen.xend.XendDomain.instance().managed_config_save(self)
         log.info("Set VCPU count on domain %s to %d", self.info['name_label'],
                  vcpus)
 
@@ -2241,6 +2240,10 @@ class XendDomainInfo:
             if self.info.has_key('machine_address_size'):
                 log.debug("_initDomain: setting maximum machine address size 
%d" % self.info['machine_address_size'])
                 xc.domain_set_machine_address_size(self.domid, 
self.info['machine_address_size'])
+
+            if self.info.has_key('suppress_spurious_page_faults') and 
self.info['suppress_spurious_page_faults']:
+                log.debug("_initDomain: suppressing spurious page faults")
+                xc.domain_suppress_spurious_page_faults(self.domid)
                 
             self._createChannels()
 
@@ -3233,6 +3236,9 @@ class XendDomainInfo:
     def get_dpcis(self):
         return XendDPCI.get_by_VM(self.info.get('uuid'))
 
+    def get_dscsis(self):
+        return XendDSCSI.get_by_VM(self.info.get('uuid'))
+
     def create_vbd(self, xenapi_vbd, vdi_image_path):
         """Create a VBD using a VDI from XendStorageRepository.
 
@@ -3412,6 +3418,60 @@ class XendDomainInfo:
                 raise XendError('Failed to create device')
 
         return dpci_uuid
+
+    def create_dscsi(self, xenapi_dscsi):
+        """Create scsi device from the passed struct in Xen API format.
+
+        @param xenapi_dscsi: DSCSI struct from Xen API
+        @rtype: string
+        @return: UUID
+        """
+
+        dscsi_uuid = uuid.createString()
+
+        # Convert xenapi to sxp
+        pscsi = XendAPIStore.get(xenapi_dscsi.get('PSCSI'), 'PSCSI')
+        devid = int(xenapi_dscsi.get('virtual_HCTL').split(':')[0])
+        target_vscsi_sxp = \
+            ['vscsi', 
+                ['dev',
+                    ['devid', devid],
+                    ['p-devname', pscsi.get_dev_name()],
+                    ['p-dev', pscsi.get_physical_HCTL()],
+                    ['v-dev', xenapi_dscsi.get('virtual_HCTL')],
+                    ['state', 'Initialising'],
+                    ['uuid', dscsi_uuid]
+                ]
+            ]
+
+        if self._stateGet() != XEN_API_VM_POWER_STATE_RUNNING:
+
+            cur_vscsi_sxp = self._getDeviceInfo_vscsi(devid, None)
+
+            if cur_vscsi_sxp is None:
+                dev_uuid = self.info.device_add('vscsi', cfg_sxp = 
target_vscsi_sxp)
+                if not dev_uuid:
+                    raise XendError('Failed to create device')
+
+            else:
+                new_vscsi_sxp = ['vscsi']
+                for existing_dev in sxp.children(cur_vscsi_sxp, 'dev'):
+                    new_vscsi_sxp.append(existing_dev)
+                new_vscsi_sxp.append(sxp.child0(target_vscsi_sxp, 'dev'))
+
+                dev_uuid = sxp.child_value(cur_vscsi_sxp, 'uuid')
+                self.info.device_update(dev_uuid, new_vscsi_sxp)
+
+            xen.xend.XendDomain.instance().managed_config_save(self)
+
+        else:
+            try:
+                self.device_configure(target_vscsi_sxp)
+
+            except Exception, exn:
+                raise XendError('Failed to create device')
+
+        return dscsi_uuid
 
 
     def destroy_device_by_uuid(self, dev_type, dev_uuid):
@@ -3480,6 +3540,41 @@ class XendDomainInfo:
             except Exception, exn:
                 raise XendError('Failed to destroy device')
 
+    def destroy_dscsi(self, dev_uuid):
+        dscsi = XendAPIStore.get(dev_uuid, 'DSCSI')
+        devid = dscsi.get_virtual_host()
+        vHCTL = dscsi.get_virtual_HCTL()
+        cur_vscsi_sxp = self._getDeviceInfo_vscsi(devid, None)
+        dev_uuid = sxp.child_value(cur_vscsi_sxp, 'uuid')
+
+        target_dev = None
+        new_vscsi_sxp = ['vscsi']
+        for dev in sxp.children(cur_vscsi_sxp, 'dev'):
+            if vHCTL == sxp.child_value(dev, 'v-dev'):
+                target_dev = dev
+            else:
+                new_vscsi_sxp.append(dev)
+
+        if target_dev is None:
+            raise XendError('Failed to destroy device')
+
+        target_dev.append(['state', 'Closing'])
+        target_vscsi_sxp = ['vscsi', target_dev]
+
+        if self._stateGet() != XEN_API_VM_POWER_STATE_RUNNING:
+
+            self.info.device_update(dev_uuid, new_vscsi_sxp)
+            if len(sxp.children(new_vscsi_sxp, 'dev')) == 0:
+                del self.info['devices'][dev_uuid]
+            xen.xend.XendDomain.instance().managed_config_save(self)
+
+        else:
+            try:
+                self.device_configure(target_vscsi_sxp)
+
+            except Exception, exn:
+                raise XendError('Failed to destroy device')
+
     def destroy_xapi_instances(self):
         """Destroy Xen-API instances stored in XendAPIStore.
         """
@@ -3504,6 +3599,10 @@ class XendDomainInfo:
         for dpci_uuid in XendDPCI.get_by_VM(self.info.get('uuid')):
             XendAPIStore.deregister(dpci_uuid, "DPCI")
             
+        # Destroy DSCSI instances.
+        for dscsi_uuid in XendDSCSI.get_by_VM(self.info.get('uuid')):
+            XendAPIStore.deregister(dscsi_uuid, "DSCSI")
+            
     def has_device(self, dev_class, dev_uuid):
         return (dev_uuid in self.info['%s_refs' % dev_class.lower()])
 
diff -r 6583186e5989 -r 46d7e12c4c91 tools/python/xen/xend/XendNode.py
--- a/tools/python/xen/xend/XendNode.py Wed Oct 22 11:38:22 2008 +0900
+++ b/tools/python/xen/xend/XendNode.py Wed Oct 22 11:46:55 2008 +0900
@@ -22,6 +22,7 @@ import xen.lowlevel.xc
 
 from xen.util import Brctl
 from xen.util import pci as PciUtil
+from xen.util import vscsi_util
 from xen.xend import XendAPIStore
 from xen.xend import osdep
 
@@ -38,7 +39,8 @@ from XendStateStore import XendStateStor
 from XendStateStore import XendStateStore
 from XendMonitor import XendMonitor
 from XendPPCI import XendPPCI
-     
+from XendPSCSI import XendPSCSI
+
 class XendNode:
     """XendNode - Represents a Domain 0 Host."""
     
@@ -53,6 +55,7 @@ class XendNode:
         * network
         * Storage Repository
         * PPCI
+        * PSCSI
         """
         
         self.xc = xen.lowlevel.xc.xc()
@@ -269,6 +272,24 @@ class XendNode:
             XendPPCI(ppci_uuid, ppci_record)
 
 
+        # Initialise PSCSIs
+        saved_pscsis = self.state_store.load_state('pscsi')
+        saved_pscsi_table = {}
+        if saved_pscsis:
+            for pscsi_uuid, pscsi_record in saved_pscsis.items():
+                try:
+                    saved_pscsi_table[pscsi_record['scsi_id']] = pscsi_uuid
+                except KeyError:
+                    pass
+
+        for pscsi_record in vscsi_util.get_all_scsi_devices():
+            if pscsi_record['scsi_id']:
+                # If saved uuid exists, use it. Otherwise create one.
+                pscsi_uuid = saved_pscsi_table.get(pscsi_record['scsi_id'],
+                                                   uuid.createString())
+                XendPSCSI(pscsi_uuid, pscsi_record)
+
+
 ##    def network_destroy(self, net_uuid):
  ##       del self.networks[net_uuid]
   ##      self.save_networks()
@@ -317,6 +338,15 @@ class XendNode:
     def get_ppci_by_uuid(self, ppci_uuid):
         if ppci_uuid in self.get_PPCI_refs():
             return ppci_uuid
+        return None
+
+
+    def get_PSCSI_refs(self):
+        return XendPSCSI.get_all()
+
+    def get_pscsi_by_uuid(self, pscsi_uuid):
+        if pscsi_uuid in self.get_PSCSI_refs():
+            return pscsi_uuid
         return None
 
 
@@ -333,6 +363,7 @@ class XendNode:
         self.save_PBDs()
         self.save_SRs()
         self.save_PPCIs()
+        self.save_PSCSIs()
 
     def save_PIFs(self):
         pif_records = dict([(pif_uuid, XendAPIStore.get(
@@ -362,6 +393,12 @@ class XendNode:
                                  ppci_uuid, "PPCI").get_record())
                             for ppci_uuid in XendPPCI.get_all()])
         self.state_store.save_state('ppci', ppci_records)
+
+    def save_PSCSIs(self):
+        pscsi_records = dict([(pscsi_uuid, XendAPIStore.get(
+                                  pscsi_uuid, "PSCSI").get_record())
+                            for pscsi_uuid in XendPSCSI.get_all()])
+        self.state_store.save_state('pscsi', pscsi_records)
 
     def shutdown(self):
         return 0
diff -r 6583186e5989 -r 46d7e12c4c91 tools/python/xen/xend/XendPSCSI.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xend/XendPSCSI.py        Wed Oct 22 11:46:55 2008 +0900
@@ -0,0 +1,143 @@
+#============================================================================
+# 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 FUJITSU LIMITED 2008
+#       Masaki Kanno <kanno.masaki@xxxxxxxxxxxxxx>
+#============================================================================
+
+from xen.xend.XendBase import XendBase
+from xen.xend.XendBase import XendAPIStore
+from xen.xend import uuid as genuuid
+
+class XendPSCSI(XendBase):
+    """Representation of a physical SCSI device."""
+
+    def getClass(self):
+        return "PSCSI"
+
+    def getAttrRO(self):
+        attrRO = ['host',
+                  'physical_host',
+                  'physical_channel',
+                  'physical_target',
+                  'physical_lun',
+                  'physical_HCTL',
+                  'vendor_name',
+                  'model',
+                  'type_id',
+                  'type',
+                  'dev_name',
+                  'sg_name',
+                  'revision',
+                  'scsi_id',
+                  'scsi_level']
+        return XendBase.getAttrRO() + attrRO
+
+    def getAttrRW(self):
+        attrRW = []
+        return XendBase.getAttrRW() + attrRW
+
+    def getAttrInst(self):
+        attrInst = []
+        return XendBase.getAttrInst() + attrInst
+
+    def getMethods(self):
+        methods = []
+        return XendBase.getMethods() + methods
+
+    def getFuncs(self):
+        funcs = []
+        return XendBase.getFuncs() + funcs
+
+    getClass    = classmethod(getClass)
+    getAttrRO   = classmethod(getAttrRO)
+    getAttrRW   = classmethod(getAttrRW)
+    getAttrInst = classmethod(getAttrInst)
+    getMethods  = classmethod(getMethods)
+    getFuncs    = classmethod(getFuncs)
+ 
+    def get_by_HCTL(self, physical_HCTL):
+        for pscsi in XendAPIStore.get_all("PSCSI"):
+            if pscsi.get_physical_HCTL() == physical_HCTL:
+                return pscsi.get_uuid()
+        return None
+
+    get_by_HCTL = classmethod(get_by_HCTL)
+
+    def __init__(self, uuid, record):
+        self.physical_HCTL = record['physical_HCTL']
+        self.vendor_name = record['vendor_name']
+        self.model = record['model']
+        self.type_id = record['type_id']
+        self.type = record['type']
+        self.dev_name = record['dev_name']
+        self.sg_name = record['sg_name']
+        self.revision = record['revision']
+        self.scsi_id = record['scsi_id']
+        self.scsi_level = record['scsi_level']
+
+        p_hctl = self.physical_HCTL.split(':')
+        self.physical_host = int(p_hctl[0])
+        self.physical_channel = int(p_hctl[1])
+        self.physical_target = int(p_hctl[2])
+        self.physical_lun = int(p_hctl[3])
+
+        XendBase.__init__(self, uuid, record)
+
+    def get_host(self):
+        from xen.xend import XendNode
+        return XendNode.instance().get_uuid()
+
+    def get_physical_host(self):
+        return self.physical_host
+
+    def get_physical_channel(self):
+        return self.physical_channel
+
+    def get_physical_target(self):
+        return self.physical_target
+
+    def get_physical_lun(self):
+        return self.physical_lun
+
+    def get_physical_HCTL(self):
+        return self.physical_HCTL
+
+    def get_vendor_name(self):
+        return self.vendor_name
+
+    def get_model(self):
+        return self.model
+
+    def get_type_id(self):
+        return self.type_id
+
+    def get_type(self):
+        return self.type
+
+    def get_dev_name(self):
+        return self.dev_name
+
+    def get_sg_name(self):
+        return self.sg_name
+
+    def get_revision(self):
+        return self.revision
+
+    def get_scsi_id(self):
+        return self.scsi_id
+
+    def get_scsi_level(self):
+        return self.scsi_level
+
diff -r 6583186e5989 -r 46d7e12c4c91 tools/python/xen/xend/server/vscsiif.py
--- a/tools/python/xen/xend/server/vscsiif.py   Wed Oct 22 11:38:22 2008 +0900
+++ b/tools/python/xen/xend/server/vscsiif.py   Wed Oct 22 11:46:55 2008 +0900
@@ -125,10 +125,10 @@ class VSCSIController(DevController):
             state = self.readBackend(devid, devpath + '/state')
             localdevid = self.readBackend(devid, devpath + '/devid')
             dev_dict = {'p-dev': pdev,
-                            'p-devname': pdevname,
-                            'v-dev': pdevname,
-                            'state': state,
-                            'devid': localdevid }
+                        'p-devname': pdevname,
+                        'v-dev': vdev,
+                        'state': state,
+                        'devid': localdevid }
             vscsi_devs.append(dev_dict)
 
         config['devs'] = vscsi_devs
@@ -168,17 +168,17 @@ class VSCSIController(DevController):
         (devid, back, front) = self.getDeviceDetails(config)
         devid = int(devid)
         vscsi_config = config['devs'][0]
-        states = config.get('states', [])
+        state = vscsi_config.get('state', '')
         driver_state = self.readBackend(devid, 'state')
         if str(xenbusState['Connected']) != driver_state:
             raise VmError("Driver status is not connected")
 
         uuid = self.readBackend(devid, 'uuid')
-        if states[0] == 'Initialising':
+        if state == 'Initialising':
             back['uuid'] = uuid
             self.writeBackend(devid, back)
 
-        elif states[0] == 'Closing':
+        elif state == 'Closing':
             found = False
             devs = self.readBackendList(devid, "vscsi-devs")
             vscsipath = "vscsi-devs/"
@@ -197,8 +197,8 @@ class VSCSIController(DevController):
                 raise VmError("Device %s not connected" % vdev)
 
         else:
-            raise XendError('Error configuring device invalid state %s'
-                                % state)
+            raise XendError("Error configuring device invalid "
+                            "state '%s'" % state)
 
         self.writeBackend(devid, 'state', str(xenbusState['Reconfiguring']))
         return self.readBackend(devid, 'uuid')
diff -r 6583186e5989 -r 46d7e12c4c91 tools/python/xen/xm/create.dtd
--- a/tools/python/xen/xm/create.dtd    Wed Oct 22 11:38:22 2008 +0900
+++ b/tools/python/xen/xm/create.dtd    Wed Oct 22 11:46:55 2008 +0900
@@ -40,6 +40,7 @@
                  vif*,
                  vtpm*,
                  pci*,
+                 vscsi*,
                  console*,
                  platform*,
                  vcpu_param*,
@@ -87,6 +88,10 @@
                  slot            CDATA #REQUIRED
                  func            CDATA #REQUIRED
                  vslt            CDATA #IMPLIED>
+
+<!ELEMENT vscsi  EMPTY>
+<!ATTLIST vscsi  p-dev           CDATA #REQUIRED
+                 v-dev           CDATA #REQUIRED>
 
 <!ELEMENT console (other_config*)>
 <!ATTLIST console protocol       (vt100|rfb|rdp) #REQUIRED>
diff -r 6583186e5989 -r 46d7e12c4c91 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Wed Oct 22 11:38:22 2008 +0900
+++ b/tools/python/xen/xm/create.py     Wed Oct 22 11:46:55 2008 +0900
@@ -583,6 +583,10 @@ gopts.var('machine_address_size', val='B
           fn=set_int, default=None,
           use="""Maximum machine address size""")
 
+gopts.var('suppress_spurious_page_faults', val='yes|no',
+          fn=set_bool, default=None,
+          use="""Do not inject spurious page faults into this guest""")
+
 def err(msg):
     """Print an error to stderr and exit.
     """
@@ -634,6 +638,9 @@ def configure_image(vals):
     if vals.machine_address_size:
         config_image.append(['machine_address_size', 
vals.machine_address_size])
 
+    if vals.suppress_spurious_page_faults:
+        config_image.append(['suppress_spurious_page_faults', 
vals.suppress_spurious_page_faults])
+
     return config_image
     
 def configure_disks(config_devs, vals):
@@ -696,11 +703,8 @@ def configure_vscsis(config_devs, vals):
 
     scsi_devices = vscsi_util.vscsi_get_scsidevices()
     for (p_dev, v_dev, backend) in vals.vscsi:
-        tmp = p_dev.split(':')
-        if len(tmp) == 4:
-            (p_hctl, block) = vscsi_util._vscsi_hctl_block(p_dev, scsi_devices)
-        else:
-            (p_hctl, block) = vscsi_util._vscsi_block_scsiid_to_hctl(p_dev, 
scsi_devices)
+        (p_hctl, devname) = \
+            vscsi_util.vscsi_get_hctl_and_devname_by(p_dev, scsi_devices)
 
         if p_hctl == None:
             raise ValueError("Cannot find device \"%s\"" % p_dev)
@@ -716,7 +720,7 @@ def configure_vscsis(config_devs, vals):
                         ['state', 'Initialising'], \
                         ['devid', devid], \
                         ['p-dev', p_hctl], \
-                        ['p-devname', block], \
+                        ['p-devname', devname], \
                         ['v-dev', v_dev] ])
 
         if vscsi_lookup_devid(devidlist, devid) == 0:
@@ -887,7 +891,7 @@ def make_config(vals):
                    'restart', 'on_poweroff',
                    'on_reboot', 'on_crash', 'vcpus', 'vcpu_avail', 'features',
                    'on_xend_start', 'on_xend_stop', 'target', 'cpuid',
-                   'cpuid_check', 'machine_address_size'])
+                   'cpuid_check', 'machine_address_size', 
'suppress_spurious_page_faults'])
 
     if vals.uuid is not None:
         config.append(['uuid', vals.uuid])
diff -r 6583186e5989 -r 46d7e12c4c91 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Wed Oct 22 11:38:22 2008 +0900
+++ b/tools/python/xen/xm/main.py       Wed Oct 22 11:46:55 2008 +0900
@@ -2235,12 +2235,34 @@ def vscsi_convert_sxp_to_dict(dev_sxp):
     return dev_dict
 
 def xm_scsi_list(args):
-    xenapi_unsupported()
     (use_long, params) = arg_check_for_resource_list(args, "scsi-list")
 
     dom = params[0]
 
-    devs = server.xend.domain.getDeviceSxprs(dom, 'vscsi')
+    devs = []
+    if serverType == SERVER_XEN_API:
+
+        dscsi_refs = server.xenapi.VM.get_DSCSIs(get_single_vm(dom))
+        dscsi_properties = \
+            map(server.xenapi.DSCSI.get_runtime_properties, dscsi_refs)
+        dscsi_dict = {}
+        for dscsi_property in dscsi_properties:
+            devid = int(dscsi_property['dev']['devid'])
+            try:
+                dscsi_sxp = dscsi_dict[devid]
+            except:
+                dscsi_sxp = [['devs', []]]
+                for key, value in dscsi_property.items():
+                    if key != 'dev':
+                        dscsi_sxp.append([key, value])
+            dev_sxp = ['dev']
+            dev_sxp.extend(map2sxp(dscsi_property['dev']))
+            dscsi_sxp[0][1].append(dev_sxp)
+            dscsi_dict[devid] = dscsi_sxp
+        devs = map2sxp(dscsi_dict)
+
+    else:
+        devs = server.xend.domain.getDeviceSxprs(dom, 'vscsi')
 
     if use_long:
         map(PrettyPrint.prettyprint, devs)
@@ -2464,37 +2486,60 @@ def xm_pci_attach(args):
     else:
         server.xend.domain.device_configure(dom, pci)
 
+def parse_scsi_configuration(p_scsi, v_hctl, state):
+    v = v_hctl.split(':')
+    if len(v) != 4:
+        raise OptionError("Invalid argument: %s" % v_hctl)
+
+    p_hctl = None
+    devname = None
+    if p_scsi is not None:
+        (p_hctl, devname) = \
+            vscsi_util.vscsi_get_hctl_and_devname_by(p_scsi)
+        if p_hctl is None:
+            raise OptionError("Cannot find device '%s'" % p_scsi)
+
+    scsi = ['vscsi']
+    scsi.append(['dev', \
+                 ['state', state], \
+                 ['devid', int(v[0])], \
+                 ['p-dev', p_hctl], \
+                 ['p-devname', devname], \
+                 ['v-dev', v_hctl] \
+               ])
+
+    return scsi
+
 def xm_scsi_attach(args):
-    xenapi_unsupported()
-
     arg_check(args, 'scsi-attach', 3, 4)
-    p_devname = args[1]
-    v_dev = args[2]
-
-    v_hctl = v_dev.split(':')
-    if len(v_hctl) != 4:
-        raise OptionError("Invalid argument: %s" % v_dev)
-
-    (p_hctl, block) = vscsi_util.vscsi_search_hctl_and_block(p_devname)
-
-    if p_hctl == None:
-        raise OptionError("Cannot find device \"%s\"" % p_devname)
-
     dom = args[0]
-    vscsi = ['vscsi']
-    vscsi.append(['dev', \
-                ['state', 'Initialising'], \
-                ['devid', v_hctl[0]], \
-                ['p-dev', p_hctl], \
-                ['p-devname', block], \
-                ['v-dev', v_dev] ])
-
-    if len(args) == 4:
-        vscsi.append(['backend', args[3]])
-
-    vscsi.append(['state', 'Initialising'])
-    vscsi.append(['devid', v_hctl[0]])
-    server.xend.domain.device_configure(dom, vscsi)
+    p_scsi = args[1]
+    v_hctl = args[2]
+    scsi = parse_scsi_configuration(p_scsi, v_hctl, 'Initialising')
+
+    if serverType == SERVER_XEN_API:
+
+        scsi_dev = sxp.children(scsi, 'dev')[0]
+        p_hctl = sxp.child_value(scsi_dev, 'p-dev')
+        target_ref = None
+        for pscsi_ref in server.xenapi.PSCSI.get_all():
+            if p_hctl == server.xenapi.PSCSI.get_physical_HCTL(pscsi_ref):
+                target_ref = pscsi_ref
+                break
+        if target_ref is None:
+            raise OptionError("Cannot find device '%s'" % p_scsi)
+
+        dscsi_record = {
+            "VM":           get_single_vm(dom),
+            "PSCSI":        target_ref,
+            "virtual_HCTL": v_hctl
+        }
+        server.xenapi.DSCSI.create(dscsi_record)
+
+    else:
+        if len(args) == 4:
+            scsi.append(['backend', args[3]])
+        server.xend.domain.device_configure(dom, scsi)
 
 def detach(args, deviceClass):
     rm_cfg = True
@@ -2587,26 +2632,25 @@ def xm_pci_detach(args):
         server.xend.domain.device_configure(dom, pci)
 
 def xm_scsi_detach(args):
-    xenapi_unsupported()
     arg_check(args, 'scsi-detach', 2)
-
-    v_dev = args[1]
-    v_hctl = v_dev.split(':')
-    if len(v_hctl) != 4:
-        raise OptionError("Invalid argument: %s" % v_dev)
-
     dom = args[0]
-    vscsi = ['vscsi']
-    vscsi.append(['dev', \
-                ['state', 'Closing'], \
-                ['devid', v_hctl[0]], \
-                ['p-dev', ''], \
-                ['p-devname', ''], \
-                ['v-dev', v_dev] ])
-
-    vscsi.append(['state', 'Closing'])
-    vscsi.append(['devid', v_hctl[0]])
-    server.xend.domain.device_configure(dom, vscsi)
+    v_hctl = args[1]
+    scsi = parse_scsi_configuration(None, v_hctl, 'Closing')
+
+    if serverType == SERVER_XEN_API:
+
+        target_ref = None
+        for dscsi_ref in server.xenapi.VM.get_DSCSIs(get_single_vm(dom)):
+            if v_hctl == server.xenapi.DSCSI.get_virtual_HCTL(dscsi_ref):
+                target_ref = dscsi_ref
+                break
+        if target_ref is None:
+            raise OptionError("Device %s not assigned" % v_hctl)
+
+        server.xenapi.DSCSI.destroy(target_ref)
+
+    else:
+        server.xend.domain.device_configure(dom, scsi)
 
 def xm_vnet_list(args):
     xenapi_unsupported()
diff -r 6583186e5989 -r 46d7e12c4c91 tools/python/xen/xm/xenapi_create.py
--- a/tools/python/xen/xm/xenapi_create.py      Wed Oct 22 11:38:22 2008 +0900
+++ b/tools/python/xen/xm/xenapi_create.py      Wed Oct 22 11:46:55 2008 +0900
@@ -375,6 +375,12 @@ class xenapi_create:
 
             self.create_pcis(vm_ref, pcis)
 
+            # Now create scsis
+
+            scsis = vm.getElementsByTagName("vscsi")
+
+            self.create_scsis(vm_ref, scsis)
+
             return vm_ref
         except:
             server.xenapi.VM.destroy(vm_ref)
@@ -532,6 +538,33 @@ class xenapi_create:
 
         return server.xenapi.DPCI.create(dpci_record)
 
+    def create_scsis(self, vm_ref, scsis):
+        log(DEBUG, "create_scsis")
+        return map(lambda scsi: self.create_scsi(vm_ref, scsi), scsis)
+
+    def create_scsi(self, vm_ref, scsi):
+        log(DEBUG, "create_scsi")
+
+        target_ref = None
+        for pscsi_ref in server.xenapi.PSCSI.get_all():
+            if scsi.attributes["p-dev"].value == 
server.xenapi.PSCSI.get_physical_HCTL(pscsi_ref):
+                target_ref = pscsi_ref
+                break
+        if target_ref is None:
+            log(DEBUG, "create_scsi: scsi device not found")
+            return None
+
+        dscsi_record = {
+            "VM":
+                vm_ref,
+            "PSCSI":
+                target_ref,
+            "virtual_HCTL":
+                scsi.attributes["v-dev"].value
+        }
+
+        return server.xenapi.DSCSI.create(dscsi_record)
+
 def get_child_by_name(exp, childname, default = None):
     try:
         return [child for child in sxp.children(exp)
@@ -562,6 +595,9 @@ class sxp2xml:
 
         pcis_sxp = map(lambda x: x[1], [device for device in devices
                                         if device[1][0] == "pci"])
+
+        scsis_sxp = map(lambda x: x[1], [device for device in devices
+                                         if device[1][0] == "vscsi"])
 
         # Create XML Document
         
@@ -704,6 +740,12 @@ class sxp2xml:
 
         map(vm.appendChild, pcis)
 
+        # And now the scsis
+
+        scsis = self.extract_scsis(scsis_sxp, document)
+
+        map(vm.appendChild, scsis)
+
         # Last but not least the consoles...
 
         consoles = self.extract_consoles(image, document)
@@ -893,6 +935,23 @@ class sxp2xml:
                 pcis.append(pci)
 
         return pcis
+
+    def extract_scsis(self, scsis_sxp, document):
+
+        scsis = []
+
+        for scsi_sxp in scsis_sxp:
+            for dev_sxp in sxp.children(scsi_sxp, "dev"):
+                scsi = document.createElement("vscsi")
+
+                scsi.attributes["p-dev"] \
+                    = get_child_by_name(dev_sxp, "p-dev")
+                scsi.attributes["v-dev"] \
+                    = get_child_by_name(dev_sxp, "v-dev")
+
+                scsis.append(scsi)
+
+        return scsis
 
     def mk_other_config(self, key, value, document):
         other_config = document.createElement("other_config")
diff -r 6583186e5989 -r 46d7e12c4c91 tools/xentrace/formats
--- a/tools/xentrace/formats    Wed Oct 22 11:38:22 2008 +0900
+++ b/tools/xentrace/formats    Wed Oct 22 11:46:55 2008 +0900
@@ -116,3 +116,7 @@ 0x0040f10e  CPU%(cpu)d  %(tsc)d (+%(relt
 0x0040f10e  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  shadow_emulate_resync_full     
   [ gfn = 0x%(1)16x ]
 0x0040f00f  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  shadow_emulate_resync_only     
   [ gfn = 0x%(1)08x ]
 0x0040f10f  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  shadow_emulate_resync_only     
   [ gfn = 0x%(1)16x ]
+
+0x00801001  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  cpu_freq_change [ %(1)dMHz -> 
%(2)dMHz ]
+0x00802001  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  cpu_idle_entry  [ C0 -> C%(1)d 
]
+0x00802002  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  cpu_idle_exit   [ C%(1)d -> C0 
]
diff -r 6583186e5989 -r 46d7e12c4c91 
unmodified_drivers/linux-2.6/platform-pci/machine_reboot.c
--- a/unmodified_drivers/linux-2.6/platform-pci/machine_reboot.c        Wed Oct 
22 11:38:22 2008 +0900
+++ b/unmodified_drivers/linux-2.6/platform-pci/machine_reboot.c        Wed Oct 
22 11:46:55 2008 +0900
@@ -10,12 +10,6 @@ struct ap_suspend_info {
        int      do_spin;
        atomic_t nr_spinning;
 };
-
-/*
- * Use a rwlock to protect the hypercall page from being executed in AP context
- * while the BSP is re-initializing it after restore.
- */
-static DEFINE_RWLOCK(suspend_lock);
 
 #ifdef CONFIG_SMP
 
@@ -33,12 +27,8 @@ static void ap_suspend(void *_info)
        atomic_inc(&info->nr_spinning);
        mb();
 
-       while (info->do_spin) {
+       while (info->do_spin)
                cpu_relax();
-               read_lock(&suspend_lock);
-               HYPERVISOR_yield();
-               read_unlock(&suspend_lock);
-       }
 
        mb();
        atomic_dec(&info->nr_spinning);
@@ -61,9 +51,7 @@ static int bp_suspend(void)
        suspend_cancelled = HYPERVISOR_suspend(0);
 
        if (!suspend_cancelled) {
-               write_lock(&suspend_lock);
                platform_pci_resume();
-               write_unlock(&suspend_lock);
                gnttab_resume();
                irq_resume();
        }
diff -r 6583186e5989 -r 46d7e12c4c91 xen/arch/ia64/vmx/vmmu.c
--- a/xen/arch/ia64/vmx/vmmu.c  Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/arch/ia64/vmx/vmmu.c  Wed Oct 22 11:46:55 2008 +0900
@@ -446,7 +446,7 @@ IA64FAULT vmx_vcpu_ptc_ga(VCPU *vcpu, u6
         do {
             cpu = v->processor;
             if (cpu != current->processor) {
-                spin_unlock_wait(&per_cpu(schedule_data, cpu).schedule_lock);
+                spin_barrier(&per_cpu(schedule_data, cpu).schedule_lock);
                 /* Flush VHPT on remote processors. */
                 smp_call_function_single(cpu, &ptc_ga_remote_func,
                                          &args, 0, 1);
diff -r 6583186e5989 -r 46d7e12c4c91 xen/arch/x86/acpi/cpu_idle.c
--- a/xen/arch/x86/acpi/cpu_idle.c      Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/arch/x86/acpi/cpu_idle.c      Wed Oct 22 11:46:55 2008 +0900
@@ -40,6 +40,7 @@
 #include <xen/guest_access.h>
 #include <xen/keyhandler.h>
 #include <xen/cpuidle.h>
+#include <xen/trace.h>
 #include <asm/cache.h>
 #include <asm/io.h>
 #include <asm/hpet.h>
@@ -251,6 +252,9 @@ static void acpi_processor_idle(void)
     switch ( cx->type )
     {
     case ACPI_STATE_C1:
+        /* Trace cpu idle entry */
+        TRACE_1D(TRC_PM_IDLE_ENTRY, 1);
+
         /*
          * Invoke C1.
          * Use the appropriate idle routine, the one that would
@@ -261,6 +265,9 @@ static void acpi_processor_idle(void)
         else 
             acpi_safe_halt();
 
+        /* Trace cpu idle exit */
+        TRACE_1D(TRC_PM_IDLE_EXIT, 1);
+
         /*
          * TBD: Can't get time duration while in C1, as resumes
          *      go to an ISR rather than here.  Need to instrument
@@ -272,12 +279,16 @@ static void acpi_processor_idle(void)
     case ACPI_STATE_C2:
         if ( local_apic_timer_c2_ok )
         {
+            /* Trace cpu idle entry */
+            TRACE_1D(TRC_PM_IDLE_ENTRY, 2);
             /* Get start time (ticks) */
             t1 = inl(pmtmr_ioport);
             /* Invoke C2 */
             acpi_idle_do_entry(cx);
             /* Get end time (ticks) */
             t2 = inl(pmtmr_ioport);
+            /* Trace cpu idle exit */
+            TRACE_1D(TRC_PM_IDLE_EXIT, 2);
 
             /* Re-enable interrupts */
             local_irq_enable();
@@ -316,6 +327,8 @@ static void acpi_processor_idle(void)
             ACPI_FLUSH_CPU_CACHE();
         }
 
+        /* Trace cpu idle entry */
+        TRACE_1D(TRC_PM_IDLE_ENTRY, cx - &power->states[0]);
         /*
          * Before invoking C3, be aware that TSC/APIC timer may be 
          * stopped by H/W. Without carefully handling of TSC/APIC stop issues,
@@ -335,6 +348,8 @@ static void acpi_processor_idle(void)
 
         /* recovering TSC */
         cstate_restore_tsc();
+        /* Trace cpu idle exit */
+        TRACE_1D(TRC_PM_IDLE_EXIT, cx - &power->states[0]);
 
         if ( power->flags.bm_check && power->flags.bm_control )
         {
diff -r 6583186e5989 -r 46d7e12c4c91 xen/arch/x86/cpu/amd.c
--- a/xen/arch/x86/cpu/amd.c    Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/arch/x86/cpu/amd.c    Wed Oct 22 11:46:55 2008 +0900
@@ -37,8 +37,8 @@ integer_param("cpuid_mask_ecx", opt_cpui
 integer_param("cpuid_mask_ecx", opt_cpuid_mask_ecx);
 integer_param("cpuid_mask_edx", opt_cpuid_mask_edx);
 static unsigned int opt_cpuid_mask_ext_ecx, opt_cpuid_mask_ext_edx;
-integer_param("cpuid_mask_ecx", opt_cpuid_mask_ext_ecx);
-integer_param("cpuid_mask_edx", opt_cpuid_mask_ext_edx);
+integer_param("cpuid_mask_ext_ecx", opt_cpuid_mask_ext_ecx);
+integer_param("cpuid_mask_ext_edx", opt_cpuid_mask_ext_edx);
 
 static inline void wrmsr_amd(unsigned int index, unsigned int lo, 
                unsigned int hi)
diff -r 6583186e5989 -r 46d7e12c4c91 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/arch/x86/domain.c     Wed Oct 22 11:46:55 2008 +0900
@@ -575,7 +575,10 @@ int arch_set_info_guest(
     v->arch.guest_context.user_regs.eflags |= 2;
 
     if ( is_hvm_vcpu(v) )
+    {
+        hvm_set_info_guest(v);
         goto out;
+    }
 
     /* Only CR0.TS is modifiable by guest or admin. */
     v->arch.guest_context.ctrlreg[0] &= X86_CR0_TS;
@@ -1252,10 +1255,10 @@ void context_switch(struct vcpu *prev, s
             flush_tlb_mask(next->vcpu_dirty_cpumask);
     }
 
-    local_irq_disable();
-
     if ( is_hvm_vcpu(prev) && !list_empty(&prev->arch.hvm_vcpu.tm_list) )
         pt_save_timer(prev);
+
+    local_irq_disable();
 
     set_current(next);
 
diff -r 6583186e5989 -r 46d7e12c4c91 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c     Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/arch/x86/domctl.c     Wed Oct 22 11:46:55 2008 +0900
@@ -1028,6 +1028,21 @@ long arch_do_domctl(
     }
     break;
 
+    case XEN_DOMCTL_suppress_spurious_page_faults:
+    {
+        struct domain *d;
+
+        ret = -ESRCH;
+        d = rcu_lock_domain_by_id(domctl->domain);
+        if ( d != NULL )
+        {
+            d->arch.suppress_spurious_page_faults = 1;
+            rcu_unlock_domain(d);
+            ret = 0;
+        }
+    }
+    break;
+
     default:
         ret = -ENOSYS;
         break;
diff -r 6583186e5989 -r 46d7e12c4c91 xen/arch/x86/hvm/svm/emulate.c
--- a/xen/arch/x86/hvm/svm/emulate.c    Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/arch/x86/hvm/svm/emulate.c    Wed Oct 22 11:46:55 2008 +0900
@@ -61,6 +61,34 @@ static unsigned long svm_rip2pointer(str
     return p;
 }
 
+static unsigned long svm_nextrip_insn_length(struct vcpu *v)
+{
+    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
+
+    if ( !cpu_has_svm_nrips || (vmcb->nextrip <= vmcb->rip) )
+        return 0;
+
+#ifndef NDEBUG
+    switch ( vmcb->exitcode )
+    {
+    case VMEXIT_CR0_READ... VMEXIT_DR15_WRITE:
+        /* faults due to instruction intercepts */
+        /* (exitcodes 84-95) are reserved */
+    case VMEXIT_IDTR_READ ... VMEXIT_TR_WRITE:
+    case VMEXIT_RDTSC ... VMEXIT_MSR:
+    case VMEXIT_VMRUN ...  VMEXIT_MWAIT_CONDITIONAL:
+        /* ...and the rest of the #VMEXITs */
+    case VMEXIT_CR0_SEL_WRITE:
+    case VMEXIT_EXCEPTION_BP:
+        break;
+    default:
+        BUG();
+    }
+#endif
+
+    return vmcb->nextrip - vmcb->rip;
+}
+
 /* First byte: Length. Following bytes: Opcode bytes. */
 #define MAKE_INSTR(nm, ...) static const u8 OPCODE_##nm[] = { __VA_ARGS__ }
 MAKE_INSTR(INVD,   2, 0x0f, 0x08);
@@ -118,6 +146,9 @@ int __get_instruction_length_from_list(s
     unsigned long fetch_addr;
     unsigned int fetch_len;
 
+    if ( (inst_len = svm_nextrip_insn_length(v)) != 0 )
+        return inst_len;
+
     /* Fetch up to the next page break; we'll fetch from the next page
      * later if we have to. */
     fetch_addr = svm_rip2pointer(v);
diff -r 6583186e5989 -r 46d7e12c4c91 xen/arch/x86/hvm/svm/intr.c
--- a/xen/arch/x86/hvm/svm/intr.c       Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/arch/x86/hvm/svm/intr.c       Wed Oct 22 11:46:55 2008 +0900
@@ -100,61 +100,6 @@ static void enable_intr_window(struct vc
     vmcb->general1_intercepts |= GENERAL1_INTERCEPT_VINTR;
 }
 
-extern int vmsi_deliver(struct domain *d, int pirq);
-static int hvm_pci_msi_assert(struct domain *d, int pirq)
-{
-    return vmsi_deliver(d, pirq);
-}
-
-static void svm_dirq_assist(struct vcpu *v)
-{
-    unsigned int irq;
-    uint32_t device, intx;
-    struct domain *d = v->domain;
-    struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
-    struct dev_intx_gsi_link *digl;
-
-    if ( !iommu_enabled || (v->vcpu_id != 0) || (hvm_irq_dpci == NULL) )
-        return;
-
-    for ( irq = find_first_bit(hvm_irq_dpci->dirq_mask, NR_IRQS);
-          irq < NR_IRQS;
-          irq = find_next_bit(hvm_irq_dpci->dirq_mask, NR_IRQS, irq + 1) )
-    {
-        if ( !test_and_clear_bit(irq, &hvm_irq_dpci->dirq_mask) )
-            continue;
-
-        spin_lock(&d->event_lock);
-        if ( test_bit(_HVM_IRQ_DPCI_MSI, &hvm_irq_dpci->mirq[irq].flags) )
-        {
-            hvm_pci_msi_assert(d, irq);
-            spin_unlock(&d->event_lock);
-            continue;
-        }
-
-        stop_timer(&hvm_irq_dpci->hvm_timer[domain_irq_to_vector(d, irq)]);
-
-        list_for_each_entry ( digl, &hvm_irq_dpci->mirq[irq].digl_list, list )
-        {
-            device = digl->device;
-            intx = digl->intx;
-            hvm_pci_intx_assert(d, device, intx);
-            hvm_irq_dpci->mirq[irq].pending++;
-        }
-
-        /*
-         * Set a timer to see if the guest can finish the interrupt or not. For
-         * example, the guest OS may unmask the PIC during boot, before the
-         * guest driver is loaded. hvm_pci_intx_assert() may succeed, but the
-         * guest will never deal with the irq, then the physical interrupt line
-         * will never be deasserted.
-         */
-        set_timer(&hvm_irq_dpci->hvm_timer[domain_irq_to_vector(d, irq)],
-                  NOW() + PT_IRQ_TIME_OUT);
-        spin_unlock(&d->event_lock);
-    }
-}
-
 asmlinkage void svm_intr_assist(void) 
 {
     struct vcpu *v = current;
@@ -163,7 +108,7 @@ asmlinkage void svm_intr_assist(void)
 
     /* Crank the handle on interrupt state. */
     pt_update_irq(v);
-    svm_dirq_assist(v);
+    hvm_dirq_assist(v);
 
     do {
         intack = hvm_vcpu_has_pending_irq(v);
diff -r 6583186e5989 -r 46d7e12c4c91 xen/arch/x86/hvm/viridian.c
--- a/xen/arch/x86/hvm/viridian.c       Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/arch/x86/hvm/viridian.c       Wed Oct 22 11:46:55 2008 +0900
@@ -244,7 +244,6 @@ int rdmsr_viridian_regs(uint32_t idx, ui
 
 int viridian_hypercall(struct cpu_user_regs *regs)
 {
-    struct domain *d = current->domain;
     int mode = hvm_guest_x86_mode(current);
     unsigned long input_params_gpa, output_params_gpa;
     uint16_t status = HV_STATUS_SUCCESS;
@@ -271,7 +270,7 @@ int viridian_hypercall(struct cpu_user_r
         };
     } output = { 0 };
 
-    ASSERT(is_viridian_domain(d));
+    ASSERT(is_viridian_domain(current->domain));
 
     switch ( mode )
     {
diff -r 6583186e5989 -r 46d7e12c4c91 xen/arch/x86/hvm/vmx/intr.c
--- a/xen/arch/x86/hvm/vmx/intr.c       Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/arch/x86/hvm/vmx/intr.c       Wed Oct 22 11:46:55 2008 +0900
@@ -103,61 +103,6 @@ static void enable_intr_window(struct vc
     }
 }
 
-extern int vmsi_deliver(struct domain *d, int pirq);
-static int hvm_pci_msi_assert(struct domain *d, int pirq)
-{
-    return vmsi_deliver(d, pirq);
-}
-
-static void vmx_dirq_assist(struct vcpu *v)
-{
-    unsigned int irq;
-    uint32_t device, intx;
-    struct domain *d = v->domain;
-    struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
-    struct dev_intx_gsi_link *digl;
-
-    if ( !iommu_enabled || (v->vcpu_id != 0) || (hvm_irq_dpci == NULL) )
-        return;
-
-    for ( irq = find_first_bit(hvm_irq_dpci->dirq_mask, NR_IRQS);
-          irq < NR_IRQS;
-          irq = find_next_bit(hvm_irq_dpci->dirq_mask, NR_IRQS, irq + 1) )
-    {
-        if ( !test_and_clear_bit(irq, &hvm_irq_dpci->dirq_mask) )
-            continue;
-
-        spin_lock(&d->event_lock);
-        if ( test_bit(_HVM_IRQ_DPCI_MSI, &hvm_irq_dpci->mirq[irq].flags) )
-        {
-            hvm_pci_msi_assert(d, irq);
-            spin_unlock(&d->event_lock);
-            continue;
-        }
-
-        stop_timer(&hvm_irq_dpci->hvm_timer[domain_irq_to_vector(d, irq)]);
-
-        list_for_each_entry ( digl, &hvm_irq_dpci->mirq[irq].digl_list, list )
-        {
-            device = digl->device;
-            intx = digl->intx;
-            hvm_pci_intx_assert(d, device, intx);
-            hvm_irq_dpci->mirq[irq].pending++;
-        }
-
-        /*
-         * Set a timer to see if the guest can finish the interrupt or not. For
-         * example, the guest OS may unmask the PIC during boot, before the
-         * guest driver is loaded. hvm_pci_intx_assert() may succeed, but the
-         * guest will never deal with the irq, then the physical interrupt line
-         * will never be deasserted.
-         */
-        set_timer(&hvm_irq_dpci->hvm_timer[domain_irq_to_vector(d, irq)],
-                  NOW() + PT_IRQ_TIME_OUT);
-        spin_unlock(&d->event_lock);
-    }
-}
-
 asmlinkage void vmx_intr_assist(void)
 {
     struct hvm_intack intack;
@@ -167,7 +112,7 @@ asmlinkage void vmx_intr_assist(void)
 
     /* Crank the handle on interrupt state. */
     pt_update_irq(v);
-    vmx_dirq_assist(v);
+    hvm_dirq_assist(v);
 
     do {
         intack = hvm_vcpu_has_pending_irq(v);
diff -r 6583186e5989 -r 46d7e12c4c91 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Wed Oct 22 11:46:55 2008 +0900
@@ -1184,6 +1184,13 @@ static void vmx_set_uc_mode(struct vcpu 
     vpid_sync_all();
 }
 
+static void vmx_set_info_guest(struct vcpu *v)
+{
+    vmx_vmcs_enter(v);
+    __vmwrite(GUEST_DR7, v->arch.guest_context.debugreg[7]);
+    vmx_vmcs_exit(v);
+}
+
 static struct hvm_function_table vmx_function_table = {
     .name                 = "VMX",
     .domain_initialise    = vmx_domain_initialise,
@@ -1214,7 +1221,8 @@ static struct hvm_function_table vmx_fun
     .msr_read_intercept   = vmx_msr_read_intercept,
     .msr_write_intercept  = vmx_msr_write_intercept,
     .invlpg_intercept     = vmx_invlpg_intercept,
-    .set_uc_mode          = vmx_set_uc_mode
+    .set_uc_mode          = vmx_set_uc_mode,
+    .set_info_guest       = vmx_set_info_guest
 };
 
 static unsigned long *vpid_bitmap;
@@ -2048,8 +2056,12 @@ asmlinkage void vmx_vmexit_handler(struc
 
     perfc_incra(vmexits, exit_reason);
 
-    if ( exit_reason != EXIT_REASON_EXTERNAL_INTERRUPT )
-        local_irq_enable();
+    /* Handle the interrupt we missed before allowing any more in. */
+    if ( exit_reason == EXIT_REASON_EXTERNAL_INTERRUPT )
+        vmx_do_extint(regs);
+
+    /* Now enable interrupts so it's safe to take locks. */
+    local_irq_enable();
 
     if ( unlikely(exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) )
         return vmx_failed_vmentry(exit_reason, regs);
@@ -2177,7 +2189,7 @@ asmlinkage void vmx_vmexit_handler(struc
         break;
     }
     case EXIT_REASON_EXTERNAL_INTERRUPT:
-        vmx_do_extint(regs);
+        /* Already handled above. */
         break;
     case EXIT_REASON_TRIPLE_FAULT:
         hvm_triple_fault();
diff -r 6583186e5989 -r 46d7e12c4c91 xen/arch/x86/irq.c
--- a/xen/arch/x86/irq.c        Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/arch/x86/irq.c        Wed Oct 22 11:46:55 2008 +0900
@@ -510,7 +510,7 @@ int pirq_guest_bind(struct vcpu *v, int 
 {
     unsigned int        vector;
     irq_desc_t         *desc;
-    irq_guest_action_t *action;
+    irq_guest_action_t *action, *newaction = NULL;
     int                 rc = 0;
     cpumask_t           cpumask = CPU_MASK_NONE;
 
@@ -520,7 +520,10 @@ int pirq_guest_bind(struct vcpu *v, int 
  retry:
     desc = domain_spin_lock_irq_desc(v->domain, irq, NULL);
     if ( desc == NULL )
-        return -EINVAL;
+    {
+        rc = -EINVAL;
+        goto out;
+    }
 
     action = (irq_guest_action_t *)desc->action;
     vector = desc - irq_desc;
@@ -533,18 +536,24 @@ int pirq_guest_bind(struct vcpu *v, int 
                     "Cannot bind IRQ %d to guest. In use by '%s'.\n",
                     irq, desc->action->name);
             rc = -EBUSY;
-            goto out;
+            goto unlock_out;
         }
 
-        action = xmalloc(irq_guest_action_t);
-        if ( (desc->action = (struct irqaction *)action) == NULL )
+        if ( newaction == NULL )
         {
+            spin_unlock_irq(&desc->lock);
+            if ( (newaction = xmalloc(irq_guest_action_t)) != NULL )
+                goto retry;
             gdprintk(XENLOG_INFO,
-                    "Cannot bind IRQ %d to guest. Out of memory.\n",
-                    irq);
+                     "Cannot bind IRQ %d to guest. Out of memory.\n",
+                     irq);
             rc = -ENOMEM;
             goto out;
         }
+
+        action = newaction;
+        desc->action = (struct irqaction *)action;
+        newaction = NULL;
 
         action->nr_guests   = 0;
         action->in_flight   = 0;
@@ -568,7 +577,7 @@ int pirq_guest_bind(struct vcpu *v, int 
                "Will not share with others.\n",
                 irq);
         rc = -EBUSY;
-        goto out;
+        goto unlock_out;
     }
     else if ( action->nr_guests == 0 )
     {
@@ -588,17 +597,21 @@ int pirq_guest_bind(struct vcpu *v, int 
         gdprintk(XENLOG_INFO, "Cannot bind IRQ %d to guest. "
                "Already at max share.\n", irq);
         rc = -EBUSY;
-        goto out;
+        goto unlock_out;
     }
 
     action->guest[action->nr_guests++] = v->domain;
 
+ unlock_out:
+    spin_unlock_irq(&desc->lock);
  out:
-    spin_unlock_irq(&desc->lock);
+    if ( newaction != NULL )
+        xfree(newaction);
     return rc;
 }
 
-static void __pirq_guest_unbind(struct domain *d, int irq, irq_desc_t *desc)
+static irq_guest_action_t *__pirq_guest_unbind(
+    struct domain *d, int irq, irq_desc_t *desc)
 {
     unsigned int        vector;
     irq_guest_action_t *action;
@@ -644,7 +657,7 @@ static void __pirq_guest_unbind(struct d
     BUG_ON(test_bit(irq, d->pirq_mask));
 
     if ( action->nr_guests != 0 )
-        return;
+        return NULL;
 
     BUG_ON(action->in_flight != 0);
 
@@ -672,15 +685,18 @@ static void __pirq_guest_unbind(struct d
     BUG_ON(!cpus_empty(action->cpu_eoi_map));
 
     desc->action = NULL;
-    xfree(action);
     desc->status &= ~IRQ_GUEST;
     desc->status &= ~IRQ_INPROGRESS;
     kill_timer(&irq_guest_eoi_timer[vector]);
     desc->handler->shutdown(vector);
+
+    /* Caller frees the old guest descriptor block. */
+    return action;
 }
 
 void pirq_guest_unbind(struct domain *d, int irq)
 {
+    irq_guest_action_t *oldaction = NULL;
     irq_desc_t *desc;
     int vector;
 
@@ -699,16 +715,19 @@ void pirq_guest_unbind(struct domain *d,
     }
     else
     {
-        __pirq_guest_unbind(d, irq, desc);
+        oldaction = __pirq_guest_unbind(d, irq, desc);
     }
 
     spin_unlock_irq(&desc->lock);
+
+    if ( oldaction != NULL )
+        xfree(oldaction);
 }
 
 int pirq_guest_force_unbind(struct domain *d, int irq)
 {
     irq_desc_t *desc;
-    irq_guest_action_t *action;
+    irq_guest_action_t *action, *oldaction = NULL;
     int i, bound = 0;
 
     WARN_ON(!spin_is_locked(&d->event_lock));
@@ -727,10 +746,14 @@ int pirq_guest_force_unbind(struct domai
         goto out;
 
     bound = 1;
-    __pirq_guest_unbind(d, irq, desc);
+    oldaction = __pirq_guest_unbind(d, irq, desc);
 
  out:
     spin_unlock_irq(&desc->lock);
+
+    if ( oldaction != NULL )
+        xfree(oldaction);
+
     return bound;
 }
 
diff -r 6583186e5989 -r 46d7e12c4c91 xen/arch/x86/mm/hap/hap.c
--- a/xen/arch/x86/mm/hap/hap.c Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/arch/x86/mm/hap/hap.c Wed Oct 22 11:46:55 2008 +0900
@@ -639,9 +639,16 @@ hap_write_p2m_entry(struct vcpu *v, unsi
 hap_write_p2m_entry(struct vcpu *v, unsigned long gfn, l1_pgentry_t *p,
                     mfn_t table_mfn, l1_pgentry_t new, unsigned int level)
 {
+    uint32_t old_flags;
+
     hap_lock(v->domain);
 
+    old_flags = l1e_get_flags(*p);
     safe_write_pte(p, new);
+    if ( (old_flags & _PAGE_PRESENT)
+         && (level == 1 || (level == 2 && (old_flags & _PAGE_PSE))) )
+             flush_tlb_mask(v->domain->domain_dirty_cpumask);
+
 #if CONFIG_PAGING_LEVELS == 3
     /* install P2M in monitor table for PAE Xen */
     if ( level == 3 )
diff -r 6583186e5989 -r 46d7e12c4c91 xen/arch/x86/mm/shadow/private.h
--- a/xen/arch/x86/mm/shadow/private.h  Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/arch/x86/mm/shadow/private.h  Wed Oct 22 11:46:55 2008 +0900
@@ -227,32 +227,40 @@ struct shadow_page_info
 struct shadow_page_info
 {
     union {
-        /* When in use, guest page we're a shadow of */
-        unsigned long backpointer;
-        /* When free, order of the freelist we're on */
-        unsigned int order;
-    };
-    union {
-        /* When in use, next shadow in this hash chain */
-        struct shadow_page_info *next_shadow;
-        /* When free, TLB flush time when freed */
-        u32 tlbflush_timestamp;
-    };
-    struct {
-        unsigned int type:5;      /* What kind of shadow is this? */
-        unsigned int pinned:1;    /* Is the shadow pinned? */
-        unsigned int count:26;    /* Reference count */
-        u32 mbz;                  /* Must be zero: this is where the owner 
-                                   * field lives in a non-shadow page */
-    } __attribute__((packed));
-    union {
-        /* For unused shadow pages, a list of pages of this order; 
-         * for pinnable shadows, if pinned, a list of other pinned shadows
-         * (see sh_type_is_pinnable() below for the definition of 
-         * "pinnable" shadow types). */
-        struct list_head list;
-        /* For non-pinnable shadows, a higher entry that points at us */
-        paddr_t up;
+        /* Ensures that shadow_page_info is same size as page_info. */
+        struct page_info page_info;
+
+        struct {
+            union {
+                /* When in use, guest page we're a shadow of */
+                unsigned long backpointer;
+                /* When free, order of the freelist we're on */
+                unsigned int order;
+            };
+            union {
+                /* When in use, next shadow in this hash chain */
+                struct shadow_page_info *next_shadow;
+                /* When free, TLB flush time when freed */
+                u32 tlbflush_timestamp;
+            };
+            struct {
+                unsigned int type:5;   /* What kind of shadow is this? */
+                unsigned int pinned:1; /* Is the shadow pinned? */
+                unsigned int count:26; /* Reference count */
+                u32 mbz;               /* Must be zero: this is where the
+                                        * owner field lives in page_info */
+            } __attribute__((packed));
+            union {
+                /* For unused shadow pages, a list of pages of this order; for 
+                 * pinnable shadows, if pinned, a list of other pinned shadows
+                 * (see sh_type_is_pinnable() below for the definition of 
+                 * "pinnable" shadow types). */
+                struct list_head list;
+                /* For non-pinnable shadows, a higher entry that points
+                 * at us. */
+                paddr_t up;
+            };
+        };
     };
 };
 
@@ -261,7 +269,8 @@ struct shadow_page_info
  * Also, the mbz field must line up with the owner field of normal 
  * pages, so they look properly like anonymous/xen pages. */
 static inline void shadow_check_page_struct_offsets(void) {
-    BUILD_BUG_ON(sizeof (struct shadow_page_info) > sizeof (struct page_info));
+    BUILD_BUG_ON(sizeof (struct shadow_page_info) !=
+                 sizeof (struct page_info));
     BUILD_BUG_ON(offsetof(struct shadow_page_info, mbz) !=
                  offsetof(struct page_info, u.inuse._domain));
 };
diff -r 6583186e5989 -r 46d7e12c4c91 xen/arch/x86/msi.c
--- a/xen/arch/x86/msi.c        Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/arch/x86/msi.c        Wed Oct 22 11:46:55 2008 +0900
@@ -364,6 +364,7 @@ static struct msi_desc* alloc_msi_entry(
 
     INIT_LIST_HEAD(&entry->list);
     entry->dev = NULL;
+    entry->remap_index = -1;
 
     return entry;
 }
diff -r 6583186e5989 -r 46d7e12c4c91 xen/arch/x86/nmi.c
--- a/xen/arch/x86/nmi.c        Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/arch/x86/nmi.c        Wed Oct 22 11:46:55 2008 +0900
@@ -72,8 +72,8 @@ int nmi_active;
 #define P6_EVNTSEL_INT         (1 << 20)
 #define P6_EVNTSEL_OS          (1 << 17)
 #define P6_EVNTSEL_USR         (1 << 16)
-#define P6_EVENT_CPU_CLOCKS_NOT_HALTED 0x79
-#define P6_NMI_EVENT           P6_EVENT_CPU_CLOCKS_NOT_HALTED
+#define P6_EVENT_CPU_CLOCKS_NOT_HALTED  0x79
+#define CORE_EVENT_CPU_CLOCKS_NOT_HALTED 0x3c
 
 #define P4_ESCR_EVENT_SELECT(N)        ((N)<<25)
 #define P4_CCCR_OVF_PMI0       (1<<26)
@@ -122,10 +122,17 @@ int __init check_nmi_watchdog (void)
 
     printk("\n");
 
-    /* now that we know it works we can reduce NMI frequency to
-       something more reasonable; makes a difference in some configs */
+    /*
+     * Now that we know it works we can reduce NMI frequency to
+     * something more reasonable; makes a difference in some configs.
+     * There's a limit to how slow we can go because writing the perfctr
+     * MSRs only sets the low 32 bits, with the top 8 bits sign-extended
+     * from those, so it's not possible to set up a delay larger than
+     * 2^31 cycles and smaller than (2^40 - 2^31) cycles. 
+     * (Intel SDM, section 18.22.2)
+     */
     if ( nmi_watchdog == NMI_LOCAL_APIC )
-        nmi_hz = 1;
+        nmi_hz = max(1ul, cpu_khz >> 20);
 
     return 0;
 }
@@ -248,7 +255,7 @@ static void __pminit setup_k7_watchdog(v
     wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
 }
 
-static void __pminit setup_p6_watchdog(void)
+static void __pminit setup_p6_watchdog(unsigned counter)
 {
     unsigned int evntsel;
 
@@ -260,7 +267,7 @@ static void __pminit setup_p6_watchdog(v
     evntsel = P6_EVNTSEL_INT
         | P6_EVNTSEL_OS
         | P6_EVNTSEL_USR
-        | P6_NMI_EVENT;
+        | counter;
 
     wrmsr(MSR_P6_EVNTSEL0, evntsel, 0);
     write_watchdog_counter("P6_PERFCTR0");
@@ -326,7 +333,9 @@ void __pminit setup_apic_nmi_watchdog(vo
     case X86_VENDOR_INTEL:
         switch (boot_cpu_data.x86) {
         case 6:
-            setup_p6_watchdog();
+            setup_p6_watchdog((boot_cpu_data.x86_model < 14) 
+                              ? P6_EVENT_CPU_CLOCKS_NOT_HALTED
+                              : CORE_EVENT_CPU_CLOCKS_NOT_HALTED);
             break;
         case 15:
             if (!setup_p4_watchdog())
diff -r 6583186e5989 -r 46d7e12c4c91 xen/arch/x86/platform_hypercall.c
--- a/xen/arch/x86/platform_hypercall.c Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/arch/x86/platform_hypercall.c Wed Oct 22 11:46:55 2008 +0900
@@ -53,15 +53,6 @@ static long cpu_frequency_change_helper(
     return cpu_frequency_change(this_cpu(freq));
 }
 
-int xenpf_copy_px_states(struct processor_performance *pxpt,
-        struct xen_processor_performance *dom0_px_info)
-{
-    if (!pxpt || !dom0_px_info)
-        return -EINVAL;
-    return  copy_from_compat(pxpt->states, dom0_px_info->states, 
-                    dom0_px_info->state_count);
-}
-
 ret_t do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op)
 {
     ret_t ret = 0;
@@ -372,12 +363,13 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
         switch ( op->u.set_pminfo.type )
         {
         case XEN_PM_PX:
-        {
-
-            ret = set_px_pminfo(op->u.set_pminfo.id,
-                                &op->u.set_pminfo.perf);
-            break;
-        }
+            if ( !(xen_processor_pmbits & XEN_PROCESSOR_PM_PX) )
+            {
+                ret = -ENOSYS;
+                break;
+            }
+            ret = set_px_pminfo(op->u.set_pminfo.id, &op->u.set_pminfo.perf);
+            break;
  
         case XEN_PM_CX:
             if ( !(xen_processor_pmbits & XEN_PROCESSOR_PM_CX) )
diff -r 6583186e5989 -r 46d7e12c4c91 xen/arch/x86/smpboot.c
--- a/xen/arch/x86/smpboot.c    Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/arch/x86/smpboot.c    Wed Oct 22 11:46:55 2008 +0900
@@ -473,13 +473,6 @@ static void construct_percpu_idt(unsigne
 {
        unsigned char idt_load[10];
 
-       /* If IDT table exists since last hotplug, reuse it */
-       if (!idt_tables[cpu]) {
-               idt_tables[cpu] = xmalloc_array(idt_entry_t, IDT_ENTRIES);
-               memcpy(idt_tables[cpu], idt_table,
-                               IDT_ENTRIES*sizeof(idt_entry_t));
-       }
-
        *(unsigned short *)(&idt_load[0]) = (IDT_ENTRIES*sizeof(idt_entry_t))-1;
        *(unsigned long  *)(&idt_load[2]) = (unsigned long)idt_tables[cpu];
        __asm__ __volatile__ ( "lidt %0" : "=m" (idt_load) );
@@ -908,6 +901,12 @@ static int __devinit do_boot_cpu(int api
        }
 #endif
 
+       if (!idt_tables[cpu]) {
+               idt_tables[cpu] = xmalloc_array(idt_entry_t, IDT_ENTRIES);
+               memcpy(idt_tables[cpu], idt_table,
+                      IDT_ENTRIES*sizeof(idt_entry_t));
+       }
+
        /*
         * This grunge runs the startup process for
         * the targeted processor.
diff -r 6583186e5989 -r 46d7e12c4c91 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/arch/x86/traps.c      Wed Oct 22 11:46:55 2008 +0900
@@ -710,7 +710,7 @@ static void pv_cpuid(struct cpu_user_reg
     if ( current->domain->domain_id != 0 )
     {
         if ( !cpuid_hypervisor_leaves(a, &a, &b, &c, &d) )
-            domain_cpuid(current->domain, a, b, &a, &b, &c, &d);
+            domain_cpuid(current->domain, a, c, &a, &b, &c, &d);
         goto out;
     }
 
@@ -1241,6 +1241,10 @@ asmlinkage void do_page_fault(struct cpu
               "Faulting linear address: %p\n",
               regs->error_code, _p(addr));
     }
+
+    if ( unlikely(current->domain->arch.suppress_spurious_page_faults
+                  && spurious_page_fault(addr, regs)) )
+        return;
 
     propagate_page_fault(addr, regs->error_code);
 }
diff -r 6583186e5989 -r 46d7e12c4c91 xen/arch/x86/x86_32/xen.lds.S
--- a/xen/arch/x86/x86_32/xen.lds.S     Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/arch/x86/x86_32/xen.lds.S     Wed Oct 22 11:46:55 2008 +0900
@@ -26,7 +26,6 @@ SECTIONS
        *(.fixup)
        *(.gnu.warning)
        } :text =0x9090
-  .text.lock : { *(.text.lock) } :text /* out-of-line lock text */
 
   _etext = .;                  /* End of text section */
 
diff -r 6583186e5989 -r 46d7e12c4c91 xen/arch/x86/x86_64/Makefile
--- a/xen/arch/x86/x86_64/Makefile      Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/arch/x86/x86_64/Makefile      Wed Oct 22 11:46:55 2008 +0900
@@ -13,6 +13,7 @@ obj-$(CONFIG_COMPAT) += physdev.o
 obj-$(CONFIG_COMPAT) += physdev.o
 obj-$(CONFIG_COMPAT) += platform_hypercall.o
 obj-$(CONFIG_COMPAT) += cpu_idle.o
+obj-$(CONFIG_COMPAT) += cpufreq.o
 
 ifeq ($(CONFIG_COMPAT),y)
 # extra dependencies
@@ -24,4 +25,5 @@ sysctl.o:     ../sysctl.c
 sysctl.o:      ../sysctl.c
 traps.o:       compat/traps.c
 cpu_idle.o:    ../acpi/cpu_idle.c
+cpufreq.o:     ../../../drivers/cpufreq/cpufreq.c
 endif
diff -r 6583186e5989 -r 46d7e12c4c91 xen/arch/x86/x86_64/cpu_idle.c
--- a/xen/arch/x86/x86_64/cpu_idle.c    Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/arch/x86/x86_64/cpu_idle.c    Wed Oct 22 11:46:55 2008 +0900
@@ -44,7 +44,7 @@ DEFINE_XEN_GUEST_HANDLE(compat_processor
     xlat_page_current = xlat_page_start; \
 } while (0)
 
-static void *xlat_malloc(unsigned long *xlat_page_current, size_t size)
+void *xlat_malloc(unsigned long *xlat_page_current, size_t size)
 {
     void *ret;
 
diff -r 6583186e5989 -r 46d7e12c4c91 xen/arch/x86/x86_64/cpufreq.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/x86_64/cpufreq.c     Wed Oct 22 11:46:55 2008 +0900
@@ -0,0 +1,91 @@
+/******************************************************************************
+ * cpufreq.c -- adapt 32b compat guest to 64b hypervisor.
+ *
+ *  Copyright (C) 2008, Liu Jinsong <jinsong.liu@xxxxxxxxx>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  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; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  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/types.h>
+#include <xen/xmalloc.h>
+#include <xen/guest_access.h>
+#include <compat/platform.h>
+
+DEFINE_XEN_GUEST_HANDLE(compat_processor_px_t);
+
+#define xlat_page_start ((unsigned long)COMPAT_ARG_XLAT_VIRT_BASE)
+
+#define xlat_malloc_init(xlat_page_current)    do { \
+    xlat_page_current = xlat_page_start; \
+} while (0)
+
+extern void *xlat_malloc(unsigned long *xlat_page_current, size_t size);
+
+#define xlat_malloc_array(_p, _t, _c) ((_t *) xlat_malloc(&_p, sizeof(_t) * 
_c))
+
+extern int 
+set_px_pminfo(uint32_t cpu, struct xen_processor_performance *perf);
+
+int 
+compat_set_px_pminfo(uint32_t cpu, struct compat_processor_performance *perf)
+{
+    struct xen_processor_performance *xen_perf;
+    unsigned long xlat_page_current;
+
+    xlat_malloc_init(xlat_page_current);
+
+    xen_perf = xlat_malloc_array(xlat_page_current,
+                                  struct xen_processor_performance, 1);
+    if ( unlikely(xen_perf == NULL) )
+       return -EFAULT;
+
+#define XLAT_processor_performance_HNDL_states(_d_, _s_) do { \
+    xen_processor_px_t *xen_states = NULL; \
+\
+    if ( likely((_s_)->state_count > 0) ) \
+    { \
+        XEN_GUEST_HANDLE(compat_processor_px_t) states; \
+        compat_processor_px_t state; \
+        int i; \
+\
+        xen_states = xlat_malloc_array(xlat_page_current, \
+                               xen_processor_px_t, (_s_)->state_count); \
+        if ( unlikely(xen_states == NULL) ) \
+            return -EFAULT; \
+\
+        if ( unlikely(!compat_handle_okay((_s_)->states, \
+                                (_s_)->state_count)) ) \
+            return -EFAULT; \
+        guest_from_compat_handle(states, (_s_)->states); \
+\
+        for ( i = 0; i < _s_->state_count; i++ ) \
+        { \
+           if ( unlikely(copy_from_guest_offset(&state, states, i, 1)) ) \
+               return -EFAULT; \
+           XLAT_processor_px(&xen_states[i], &state); \
+        } \
+    } \
+\
+    set_xen_guest_handle((_d_)->states, xen_states); \
+} while (0)
+    XLAT_processor_performance(xen_perf, perf);
+#undef XLAT_processor_performance_HNDL_states
+
+    return set_px_pminfo(cpu, xen_perf);
+}
diff -r 6583186e5989 -r 46d7e12c4c91 xen/arch/x86/x86_64/mm.c
--- a/xen/arch/x86/x86_64/mm.c  Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/arch/x86/x86_64/mm.c  Wed Oct 22 11:46:55 2008 +0900
@@ -252,8 +252,6 @@ void __init subarch_init_memory(void)
     BUILD_BUG_ON(offsetof(struct page_info, u.inuse._domain) != 
                  (offsetof(struct page_info, count_info) + sizeof(u32)));
     BUILD_BUG_ON((offsetof(struct page_info, count_info) & 7) != 0);
-    BUILD_BUG_ON(sizeof(struct page_info) !=
-                 (32 + BITS_TO_LONGS(NR_CPUS)*sizeof(long)));
 
     /* M2P table is mappable read-only by privileged domains. */
     for ( v  = RDWR_MPT_VIRT_START;
diff -r 6583186e5989 -r 46d7e12c4c91 xen/arch/x86/x86_64/platform_hypercall.c
--- a/xen/arch/x86/x86_64/platform_hypercall.c  Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/arch/x86/x86_64/platform_hypercall.c  Wed Oct 22 11:46:55 2008 +0900
@@ -11,13 +11,13 @@ DEFINE_XEN_GUEST_HANDLE(compat_platform_
 #define xen_platform_op_t   compat_platform_op_t
 #define do_platform_op(x)   compat_platform_op(_##x)
 
-#define xenpf_copy_px_states compat_xenpf_copy_px_states
-
 #define xen_processor_px    compat_processor_px
 #define xen_processor_px_t  compat_processor_px_t
 #define xen_processor_performance    compat_processor_performance
 #define xen_processor_performance_t  compat_processor_performance_t
 #define xenpf_set_processor_pminfo   compat_pf_set_processor_pminfo
+
+#define set_px_pminfo          compat_set_px_pminfo
 
 #define xen_processor_power     compat_processor_power
 #define xen_processor_power_t   compat_processor_power_t
diff -r 6583186e5989 -r 46d7e12c4c91 xen/arch/x86/x86_64/xen.lds.S
--- a/xen/arch/x86/x86_64/xen.lds.S     Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/arch/x86/x86_64/xen.lds.S     Wed Oct 22 11:46:55 2008 +0900
@@ -24,7 +24,6 @@ SECTIONS
        *(.fixup)
        *(.gnu.warning)
        } :text = 0x9090
-  .text.lock : { *(.text.lock) } :text /* out-of-line lock text */
 
   _etext = .;                  /* End of text section */
 
diff -r 6583186e5989 -r 46d7e12c4c91 xen/arch/x86/x86_emulate/x86_emulate.c
--- a/xen/arch/x86/x86_emulate/x86_emulate.c    Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c    Wed Oct 22 11:46:55 2008 +0900
@@ -236,7 +236,8 @@ static uint8_t twobyte_table[256] = {
     DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
     ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem16|ModRM|Mov,
     /* 0xC0 - 0xC7 */
-    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, 0, 0,
+    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
+    0, DstMem|SrcReg|ModRM|Mov,
     0, 0, 0, ImplicitOps|ModRM,
     /* 0xC8 - 0xCF */
     ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
@@ -3910,6 +3911,12 @@ x86_emulate(
         }
         goto add;
 
+    case 0xc3: /* movnti */
+        /* Ignore the non-temporal hint for now. */
+        generate_exception_if(dst.bytes <= 2, EXC_UD, -1);
+        dst.val = src.val;
+        break;
+
     case 0xc7: /* Grp9 (cmpxchg8b/cmpxchg16b) */ {
         unsigned long old[2], exp[2], new[2];
         unsigned int i;
diff -r 6583186e5989 -r 46d7e12c4c91 xen/common/Makefile
--- a/xen/common/Makefile       Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/common/Makefile       Wed Oct 22 11:46:55 2008 +0900
@@ -16,6 +16,7 @@ obj-y += schedule.o
 obj-y += schedule.o
 obj-y += shutdown.o
 obj-y += softirq.o
+obj-y += spinlock.o
 obj-y += stop_machine.o
 obj-y += string.o
 obj-y += symbols.o
@@ -25,7 +26,7 @@ obj-y += trace.o
 obj-y += trace.o
 obj-y += version.o
 obj-y += vsprintf.o
-obj-y += xmalloc.o
+obj-y += xmalloc_tlsf.o
 obj-y += rcupdate.o
 
 obj-$(perfc)       += perfc.o
diff -r 6583186e5989 -r 46d7e12c4c91 xen/common/kernel.c
--- a/xen/common/kernel.c       Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/common/kernel.c       Wed Oct 22 11:46:55 2008 +0900
@@ -75,8 +75,7 @@ void cmdline_parse(char *cmdline)
                 strlcpy(param->var, optval, param->len);
                 break;
             case OPT_UINT:
-                *(unsigned int *)param->var =
-                    simple_strtol(optval, (const char **)&optval, 0);
+                *(unsigned int *)param->var = simple_strtol(optval, NULL, 0);
                 break;
             case OPT_BOOL:
             case OPT_INVBOOL:
diff -r 6583186e5989 -r 46d7e12c4c91 xen/common/schedule.c
--- a/xen/common/schedule.c     Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/common/schedule.c     Wed Oct 22 11:46:55 2008 +0900
@@ -455,6 +455,10 @@ static long do_poll(struct sched_poll *s
         goto out;
 #endif
 
+    rc = 0;
+    if ( local_events_need_delivery() )
+        goto out;
+
     for ( i = 0; i < sched_poll->nr_ports; i++ )
     {
         rc = -EFAULT;
diff -r 6583186e5989 -r 46d7e12c4c91 xen/common/spinlock.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/common/spinlock.c     Wed Oct 22 11:46:55 2008 +0900
@@ -0,0 +1,154 @@
+#include <xen/config.h>
+#include <xen/smp.h>
+#include <xen/spinlock.h>
+
+void _spin_lock(spinlock_t *lock)
+{
+    _raw_spin_lock(&lock->raw);
+}
+
+void _spin_lock_irq(spinlock_t *lock)
+{
+    local_irq_disable();
+    _raw_spin_lock(&lock->raw);
+}
+
+unsigned long _spin_lock_irqsave(spinlock_t *lock)
+{
+    unsigned long flags;
+    local_irq_save(flags);
+    _raw_spin_lock(&lock->raw);
+    return flags;
+}
+
+void _spin_unlock(spinlock_t *lock)
+{
+    _raw_spin_unlock(&lock->raw);
+}
+
+void _spin_unlock_irq(spinlock_t *lock)
+{
+    _raw_spin_unlock(&lock->raw);
+    local_irq_enable();
+}
+
+void _spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags)
+{
+    _raw_spin_unlock(&lock->raw);
+    local_irq_restore(flags);
+}
+
+int _spin_is_locked(spinlock_t *lock)
+{
+    return _raw_spin_is_locked(&lock->raw);
+}
+
+int _spin_trylock(spinlock_t *lock)
+{
+    return _raw_spin_trylock(&lock->raw);
+}
+
+void _spin_barrier(spinlock_t *lock)
+{
+    do { mb(); } while ( _raw_spin_is_locked(&lock->raw) );
+    mb();
+}
+
+void _spin_lock_recursive(spinlock_t *lock)
+{
+    int cpu = smp_processor_id();
+
+    /* Don't allow overflow of recurse_cpu field. */
+    BUILD_BUG_ON(NR_CPUS > 0xfffu);
+
+    if ( likely(lock->recurse_cpu != cpu) )
+    {
+        spin_lock(lock);
+        lock->recurse_cpu = cpu;
+    }
+
+    /* We support only fairly shallow recursion, else the counter overflows. */
+    ASSERT(lock->recurse_cnt < 0xfu);
+    lock->recurse_cnt++;
+}
+
+void _spin_unlock_recursive(spinlock_t *lock)
+{
+    if ( likely(--lock->recurse_cnt == 0) )
+    {
+        lock->recurse_cpu = 0xfffu;
+        spin_unlock(lock);
+    }
+}
+
+void _read_lock(rwlock_t *lock)
+{
+    _raw_read_lock(&lock->raw);
+}
+
+void _read_lock_irq(rwlock_t *lock)
+{
+    local_irq_disable();
+    _raw_read_lock(&lock->raw);
+}
+
+unsigned long _read_lock_irqsave(rwlock_t *lock)
+{
+    unsigned long flags;
+    local_irq_save(flags);
+    _raw_read_lock(&lock->raw);
+    return flags;
+}
+
+void _read_unlock(rwlock_t *lock)
+{
+    _raw_read_unlock(&lock->raw);
+}
+
+void _read_unlock_irq(rwlock_t *lock)
+{
+    _raw_read_unlock(&lock->raw);
+    local_irq_enable();
+}
+
+void _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
+{
+    _raw_read_unlock(&lock->raw);
+    local_irq_restore(flags);
+}
+
+void _write_lock(rwlock_t *lock)
+{
+    _raw_write_lock(&lock->raw);
+}
+
+void _write_lock_irq(rwlock_t *lock)
+{
+    local_irq_disable();
+    _raw_write_lock(&lock->raw);
+}
+
+unsigned long _write_lock_irqsave(rwlock_t *lock)
+{
+    unsigned long flags;
+    local_irq_save(flags);
+    _raw_write_lock(&lock->raw);
+    return flags;
+}
+
+void _write_unlock(rwlock_t *lock)
+{
+    _raw_write_unlock(&lock->raw);
+}
+
+void _write_unlock_irq(rwlock_t *lock)
+{
+    _raw_write_unlock(&lock->raw);
+    local_irq_enable();
+}
+
+void _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
+{
+    _raw_write_unlock(&lock->raw);
+    local_irq_restore(flags);
+}
diff -r 6583186e5989 -r 46d7e12c4c91 xen/common/timer.c
--- a/xen/common/timer.c        Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/common/timer.c        Wed Oct 22 11:46:55 2008 +0900
@@ -114,34 +114,19 @@ static int remove_from_heap(struct timer
 
 
 /* Add new entry @t to @heap. Return TRUE if new top of heap. */
-static int add_to_heap(struct timer ***pheap, struct timer *t)
-{
-    struct timer **heap = *pheap;
+static int add_to_heap(struct timer **heap, struct timer *t)
+{
     int sz = GET_HEAP_SIZE(heap);
 
-    /* Copy the heap if it is full. */
+    /* Fail if the heap is full. */
     if ( unlikely(sz == GET_HEAP_LIMIT(heap)) )
-    {
-        /* old_limit == (2^n)-1; new_limit == (2^(n+4))-1 */
-        int old_limit = GET_HEAP_LIMIT(heap);
-        int new_limit = ((old_limit + 1) << 4) - 1;
-        if ( in_irq() )
-            goto out;
-        heap = xmalloc_array(struct timer *, new_limit + 1);
-        if ( heap == NULL )
-            goto out;
-        memcpy(heap, *pheap, (old_limit + 1) * sizeof(*heap));
-        SET_HEAP_LIMIT(heap, new_limit);
-        if ( old_limit != 0 )
-            xfree(*pheap);
-        *pheap = heap;
-    }
+        return 0;
 
     SET_HEAP_SIZE(heap, ++sz);
     heap[sz] = t;
     t->heap_offset = sz;
     up_heap(heap, sz);
- out:
+
     return (t->heap_offset == 1);
 }
 
@@ -210,7 +195,7 @@ static int add_entry(struct timers *time
     /* Try to add to heap. t->heap_offset indicates whether we succeed. */
     t->heap_offset = 0;
     t->status = TIMER_STATUS_in_heap;
-    rc = add_to_heap(&timers->heap, t);
+    rc = add_to_heap(timers->heap, t);
     if ( t->heap_offset != 0 )
         return rc;
 
@@ -368,6 +353,27 @@ static void timer_softirq_action(void)
     void          *data;
 
     ts = &this_cpu(timers);
+    heap = ts->heap;
+
+    /* If we are using overflow linked list, try to allocate a larger heap. */
+    if ( unlikely(ts->list != NULL) )
+    {
+        /* old_limit == (2^n)-1; new_limit == (2^(n+4))-1 */
+        int old_limit = GET_HEAP_LIMIT(heap);
+        int new_limit = ((old_limit + 1) << 4) - 1;
+        struct timer **newheap = xmalloc_array(struct timer *, new_limit + 1);
+        if ( newheap != NULL )
+        {
+            spin_lock_irq(&ts->lock);
+            memcpy(newheap, heap, (old_limit + 1) * sizeof(*heap));
+            SET_HEAP_LIMIT(newheap, new_limit);
+            ts->heap = newheap;
+            spin_unlock_irq(&ts->lock);
+            if ( old_limit != 0 )
+                xfree(heap);
+            heap = newheap;
+        }
+    }
 
     spin_lock_irq(&ts->lock);
 
@@ -380,9 +386,8 @@ static void timer_softirq_action(void)
         t->status = TIMER_STATUS_inactive;
         add_entry(ts, t);
     }
-    
-    heap = ts->heap;
-    now  = NOW();
+
+    now = NOW();
 
     while ( (GET_HEAP_SIZE(heap) != 0) &&
             ((t = heap[1])->expires < (now + TIMER_SLOP)) )
@@ -397,9 +402,6 @@ static void timer_softirq_action(void)
         spin_unlock_irq(&ts->lock);
         (*fn)(data);
         spin_lock_irq(&ts->lock);
-
-        /* Heap may have grown while the lock was released. */
-        heap = ts->heap;
     }
 
     deadline = GET_HEAP_SIZE(heap) ? heap[1]->expires : 0;
diff -r 6583186e5989 -r 46d7e12c4c91 xen/common/xmalloc_tlsf.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/common/xmalloc_tlsf.c Wed Oct 22 11:46:55 2008 +0900
@@ -0,0 +1,599 @@
+/*
+ * Two Levels Segregate Fit memory allocator (TLSF)
+ * Version 2.3.2
+ *
+ * Written by Miguel Masmano Tello <mimastel@xxxxxxxxxxxxx>
+ *
+ * Thanks to Ismael Ripoll for his suggestions and reviews
+ *
+ * Copyright (C) 2007, 2006, 2005, 2004
+ *
+ * This code is released using a dual license strategy: GPL/LGPL
+ * You can choose the licence that better fits your requirements.
+ *
+ * Released under the terms of the GNU General Public License Version 2.0
+ * Released under the terms of the GNU Lesser General Public License 
+ * Version 2.1
+ *
+ * This is kernel port of TLSF allocator.
+ * Original code can be found at: http://rtportal.upv.es/rtmalloc/
+ * Adapted for Linux by Nitin Gupta (nitingupta910@xxxxxxxxx)
+ * (http://code.google.com/p/compcache/source/browse/trunk/sub-projects
+ *  /allocators/tlsf-kmod r229 dated Aug 27, 2008
+ * Adapted for Xen by Dan Magenheimer (dan.magenheimer@xxxxxxxxxx)
+ */
+
+#include <xen/config.h>
+#include <xen/irq.h>
+#include <xen/mm.h>
+#include <asm/time.h>
+
+#define MAX_POOL_NAME_LEN       16
+
+/* Some IMPORTANT TLSF parameters */
+#define MEM_ALIGN       (sizeof(void *) * 2)
+#define MEM_ALIGN_MASK  (~(MEM_ALIGN - 1))
+
+#define MAX_FLI         (30)
+#define MAX_LOG2_SLI    (5)
+#define MAX_SLI         (1 << MAX_LOG2_SLI)
+
+#define FLI_OFFSET      (6)
+/* tlsf structure just will manage blocks bigger than 128 bytes */
+#define SMALL_BLOCK     (128)
+#define REAL_FLI        (MAX_FLI - FLI_OFFSET)
+#define MIN_BLOCK_SIZE  (sizeof(struct free_ptr))
+#define BHDR_OVERHEAD   (sizeof(struct bhdr) - MIN_BLOCK_SIZE)
+
+#define PTR_MASK        (sizeof(void *) - 1)
+#define BLOCK_SIZE_MASK (0xFFFFFFFF - PTR_MASK)
+
+#define GET_NEXT_BLOCK(addr, r) ((struct bhdr *) \
+                                ((char *)(addr) + (r)))
+#define ROUNDUP_SIZE(r)         (((r) + MEM_ALIGN - 1) & MEM_ALIGN_MASK)
+#define ROUNDDOWN_SIZE(r)       ((r) & MEM_ALIGN_MASK)
+#define ROUNDUP_PAGE(r)         (((r) + PAGE_SIZE - 1) & PAGE_MASK)
+
+#define BLOCK_STATE     (0x1)
+#define PREV_STATE      (0x2)
+
+/* bit 0 of the block size */
+#define FREE_BLOCK      (0x1)
+#define USED_BLOCK      (0x0)
+
+/* bit 1 of the block size */
+#define PREV_FREE       (0x2)
+#define PREV_USED       (0x0)
+
+static spinlock_t pool_list_lock;
+static struct list_head pool_list_head;
+
+struct free_ptr {
+    struct bhdr *prev;
+    struct bhdr *next;
+};
+
+struct bhdr {
+    /* All blocks in a region are linked in order of physical address */
+    struct bhdr *prev_hdr;
+    /*
+     * The size is stored in bytes
+     *  bit 0: block is free, if set
+     *  bit 1: previous block is free, if set
+     */
+    u32 size;
+    /* Free blocks in individual freelists are linked */
+    union {
+        struct free_ptr free_ptr;
+        u8 buffer[sizeof(struct free_ptr)];
+    } ptr;
+};
+
+struct xmem_pool {
+    /* First level bitmap (REAL_FLI bits) */
+    u32 fl_bitmap;
+
+    /* Second level bitmap */
+    u32 sl_bitmap[REAL_FLI];
+
+    /* Free lists */
+    struct bhdr *matrix[REAL_FLI][MAX_SLI];
+
+    spinlock_t lock;
+
+    unsigned long init_size;
+    unsigned long max_size;
+    unsigned long grow_size;
+
+    /* Basic stats */
+    unsigned long used_size;
+    unsigned long num_regions;
+
+    /* User provided functions for expanding/shrinking pool */
+    xmem_pool_get_memory *get_mem;
+    xmem_pool_put_memory *put_mem;
+
+    struct list_head list;
+
+    void *init_region;
+    char name[MAX_POOL_NAME_LEN];
+};
+
+/*
+ * Helping functions
+ */
+
+/**
+ * Returns indexes (fl, sl) of the list used to serve request of size r
+ */
+static inline void MAPPING_SEARCH(unsigned long *r, int *fl, int *sl)
+{
+    int t;
+
+    if ( *r < SMALL_BLOCK )
+    {
+        *fl = 0;
+        *sl = *r / (SMALL_BLOCK / MAX_SLI);
+    }
+    else
+    {
+        t = (1 << (fls(*r) - 1 - MAX_LOG2_SLI)) - 1;
+        *r = *r + t;
+        *fl = fls(*r) - 1;
+        *sl = (*r >> (*fl - MAX_LOG2_SLI)) - MAX_SLI;
+        *fl -= FLI_OFFSET;
+        /*if ((*fl -= FLI_OFFSET) < 0) // FL will be always >0!
+         *fl = *sl = 0;
+         */
+        *r &= ~t;
+    }
+}
+
+/**
+ * Returns indexes (fl, sl) which is used as starting point to search
+ * for a block of size r. It also rounds up requested size(r) to the
+ * next list.
+ */
+static inline void MAPPING_INSERT(unsigned long r, int *fl, int *sl)
+{
+    if ( r < SMALL_BLOCK )
+    {
+        *fl = 0;
+        *sl = r / (SMALL_BLOCK / MAX_SLI);
+    }
+    else
+    {
+        *fl = fls(r) - 1;
+        *sl = (r >> (*fl - MAX_LOG2_SLI)) - MAX_SLI;
+        *fl -= FLI_OFFSET;
+    }
+}
+
+/**
+ * Returns first block from a list that hold blocks larger than or
+ * equal to the one pointed by the indexes (fl, sl)
+ */
+static inline struct bhdr *FIND_SUITABLE_BLOCK(struct xmem_pool *p, int *fl,
+                                               int *sl)
+{
+    u32 tmp = p->sl_bitmap[*fl] & (~0 << *sl);
+    struct bhdr *b = NULL;
+
+    if ( tmp )
+    {
+        *sl = ffs(tmp) - 1;
+        b = p->matrix[*fl][*sl];
+    }
+    else
+    {
+        *fl = ffs(p->fl_bitmap & (~0 << (*fl + 1))) - 1;
+        if ( likely(*fl > 0) )
+        {
+            *sl = ffs(p->sl_bitmap[*fl]) - 1;
+            b = p->matrix[*fl][*sl];
+        }
+    }
+
+    return b;
+}
+
+/**
+ * Remove first free block(b) from free list with indexes (fl, sl).
+ */
+static inline void EXTRACT_BLOCK_HDR(struct bhdr *b, struct xmem_pool *p, int 
fl,
+                                     int sl)
+{
+    p->matrix[fl][sl] = b->ptr.free_ptr.next;
+    if ( p->matrix[fl][sl] )
+    {
+        p->matrix[fl][sl]->ptr.free_ptr.prev = NULL;
+    }
+    else
+    {
+        clear_bit(sl, &p->sl_bitmap[fl]);
+        if ( !p->sl_bitmap[fl] )
+            clear_bit(fl, &p->fl_bitmap);
+    }
+    b->ptr.free_ptr = (struct free_ptr) {NULL, NULL};
+}
+
+/**
+ * Removes block(b) from free list with indexes (fl, sl)
+ */
+static inline void EXTRACT_BLOCK(struct bhdr *b, struct xmem_pool *p, int fl,
+                                 int sl)
+{
+    if ( b->ptr.free_ptr.next )
+        b->ptr.free_ptr.next->ptr.free_ptr.prev =
+            b->ptr.free_ptr.prev;
+    if ( b->ptr.free_ptr.prev )
+        b->ptr.free_ptr.prev->ptr.free_ptr.next =
+            b->ptr.free_ptr.next;
+    if ( p->matrix[fl][sl] == b )
+    {
+        p->matrix[fl][sl] = b->ptr.free_ptr.next;
+        if ( !p->matrix[fl][sl] )
+        {
+            clear_bit(sl, &p->sl_bitmap[fl]);
+            if ( !p->sl_bitmap[fl] )
+                clear_bit (fl, &p->fl_bitmap);
+        }
+    }
+    b->ptr.free_ptr = (struct free_ptr) {NULL, NULL};
+}
+
+/**
+ * Insert block(b) in free list with indexes (fl, sl)
+ */
+static inline void INSERT_BLOCK(struct bhdr *b, struct xmem_pool *p, int fl, 
int sl)
+{
+    b->ptr.free_ptr = (struct free_ptr) {NULL, p->matrix[fl][sl]};
+    if ( p->matrix[fl][sl] )
+        p->matrix[fl][sl]->ptr.free_ptr.prev = b;
+    p->matrix[fl][sl] = b;
+    set_bit(sl, &p->sl_bitmap[fl]);
+    set_bit(fl, &p->fl_bitmap);
+}
+
+/**
+ * Region is a virtually contiguous memory region and Pool is
+ * collection of such regions
+ */
+static inline void ADD_REGION(void *region, unsigned long region_size,
+                              struct xmem_pool *pool)
+{
+    int fl, sl;
+    struct bhdr *b, *lb;
+
+    b = (struct bhdr *)(region);
+    b->prev_hdr = NULL;
+    b->size = ROUNDDOWN_SIZE(region_size - 2 * BHDR_OVERHEAD)
+        | FREE_BLOCK | PREV_USED;
+    MAPPING_INSERT(b->size & BLOCK_SIZE_MASK, &fl, &sl);
+    INSERT_BLOCK(b, pool, fl, sl);
+    /* The sentinel block: allows us to know when we're in the last block */
+    lb = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE_MASK);
+    lb->prev_hdr = b;
+    lb->size = 0 | USED_BLOCK | PREV_FREE;
+    pool->used_size += BHDR_OVERHEAD; /* only sentinel block is "used" */
+    pool->num_regions++;
+}
+
+/*
+ * TLSF pool-based allocator start.
+ */
+
+struct xmem_pool *xmem_pool_create(
+    const char *name,
+    xmem_pool_get_memory get_mem,
+    xmem_pool_put_memory put_mem,
+    unsigned long init_size,
+    unsigned long max_size,
+    unsigned long grow_size)
+{
+    struct xmem_pool *pool;
+    void *region;
+    int pool_bytes, pool_order;
+
+    BUG_ON(max_size && (max_size < init_size));
+
+    pool_bytes = ROUNDUP_SIZE(sizeof(*pool));
+    pool_order = get_order_from_bytes(pool_bytes);
+
+    pool = (void *)alloc_xenheap_pages(pool_order);
+    if ( pool == NULL )
+        return NULL;
+    memset(pool, 0, pool_bytes);
+
+    /* Round to next page boundary */
+    init_size = ROUNDUP_PAGE(init_size);
+    max_size = ROUNDUP_PAGE(max_size);
+    grow_size = ROUNDUP_PAGE(grow_size);
+
+    /* pool global overhead not included in used size */
+    pool->used_size = 0;
+
+    pool->init_size = init_size;
+    pool->max_size = max_size;
+    pool->grow_size = grow_size;
+    pool->get_mem = get_mem;
+    pool->put_mem = put_mem;
+    strlcpy(pool->name, name, sizeof(pool->name));
+    region = get_mem(init_size);
+    if ( region == NULL )
+        goto out_region;
+    ADD_REGION(region, init_size, pool);
+    pool->init_region = region;
+
+    spin_lock_init(&pool->lock);
+
+    spin_lock(&pool_list_lock);
+    list_add_tail(&pool->list, &pool_list_head);
+    spin_unlock(&pool_list_lock);
+
+    return pool;
+
+ out_region:
+    free_xenheap_pages(pool, pool_order);
+    return NULL;
+}
+
+unsigned long xmem_pool_get_used_size(struct xmem_pool *pool)
+{
+    return pool->used_size;
+}
+
+unsigned long xmem_pool_get_total_size(struct xmem_pool *pool)
+{
+    unsigned long total;
+    total = ROUNDUP_SIZE(sizeof(*pool))
+        + pool->init_size
+        + (pool->num_regions - 1) * pool->grow_size;
+    return total;
+}
+
+void xmem_pool_destroy(struct xmem_pool *pool) 
+{
+    if ( pool == NULL )
+        return;
+
+    /* User is destroying without ever allocating from this pool */
+    if ( xmem_pool_get_used_size(pool) == BHDR_OVERHEAD )
+    {
+        pool->put_mem(pool->init_region);
+        pool->used_size -= BHDR_OVERHEAD;
+    }
+
+    /* Check for memory leaks in this pool */
+    if ( xmem_pool_get_used_size(pool) )
+        printk("memory leak in pool: %s (%p). "
+               "%lu bytes still in use.\n",
+               pool->name, pool, xmem_pool_get_used_size(pool));
+
+    spin_lock(&pool_list_lock);
+    list_del_init(&pool->list);
+    spin_unlock(&pool_list_lock);
+    pool->put_mem(pool);
+}
+
+void *xmem_pool_alloc(unsigned long size, struct xmem_pool *pool)
+{
+    struct bhdr *b, *b2, *next_b, *region;
+    int fl, sl;
+    unsigned long tmp_size;
+
+    size = (size < MIN_BLOCK_SIZE) ? MIN_BLOCK_SIZE : ROUNDUP_SIZE(size);
+    /* Rounding up the requested size and calculating fl and sl */
+
+    spin_lock(&pool->lock);
+ retry_find:
+    MAPPING_SEARCH(&size, &fl, &sl);
+
+    /* Searching a free block */
+    if ( !(b = FIND_SUITABLE_BLOCK(pool, &fl, &sl)) )
+    {
+        /* Not found */
+        if ( size > (pool->grow_size - 2 * BHDR_OVERHEAD) )
+            goto out_locked;
+        if ( pool->max_size && (pool->init_size +
+                                pool->num_regions * pool->grow_size
+                                > pool->max_size) )
+            goto out_locked;
+        spin_unlock(&pool->lock);
+        if ( (region = pool->get_mem(pool->grow_size)) == NULL )
+            goto out;
+        spin_lock(&pool->lock);
+        ADD_REGION(region, pool->grow_size, pool);
+        goto retry_find;
+    }
+    EXTRACT_BLOCK_HDR(b, pool, fl, sl);
+
+    /*-- found: */
+    next_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE_MASK);
+    /* Should the block be split? */
+    tmp_size = (b->size & BLOCK_SIZE_MASK) - size;
+    if ( tmp_size >= sizeof(struct bhdr) )
+    {
+        tmp_size -= BHDR_OVERHEAD;
+        b2 = GET_NEXT_BLOCK(b->ptr.buffer, size);
+
+        b2->size = tmp_size | FREE_BLOCK | PREV_USED;
+        b2->prev_hdr = b;
+
+        next_b->prev_hdr = b2;
+
+        MAPPING_INSERT(tmp_size, &fl, &sl);
+        INSERT_BLOCK(b2, pool, fl, sl);
+
+        b->size = size | (b->size & PREV_STATE);
+    }
+    else
+    {
+        next_b->size &= (~PREV_FREE);
+        b->size &= (~FREE_BLOCK); /* Now it's used */
+    }
+
+    pool->used_size += (b->size & BLOCK_SIZE_MASK) + BHDR_OVERHEAD;
+
+    spin_unlock(&pool->lock);
+    return (void *)b->ptr.buffer;
+
+    /* Failed alloc */
+ out_locked:
+    spin_unlock(&pool->lock);
+
+ out:
+    return NULL;
+}
+
+void xmem_pool_free(void *ptr, struct xmem_pool *pool)
+{
+    struct bhdr *b, *tmp_b;
+    int fl = 0, sl = 0;
+
+    if ( unlikely(ptr == NULL) )
+        return;
+
+    b = (struct bhdr *)((char *) ptr - BHDR_OVERHEAD);
+
+    spin_lock(&pool->lock);
+    b->size |= FREE_BLOCK;
+    pool->used_size -= (b->size & BLOCK_SIZE_MASK) + BHDR_OVERHEAD;
+    b->ptr.free_ptr = (struct free_ptr) { NULL, NULL};
+    tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE_MASK);
+    if ( tmp_b->size & FREE_BLOCK )
+    {
+        MAPPING_INSERT(tmp_b->size & BLOCK_SIZE_MASK, &fl, &sl);
+        EXTRACT_BLOCK(tmp_b, pool, fl, sl);
+        b->size += (tmp_b->size & BLOCK_SIZE_MASK) + BHDR_OVERHEAD;
+    }
+    if ( b->size & PREV_FREE )
+    {
+        tmp_b = b->prev_hdr;
+        MAPPING_INSERT(tmp_b->size & BLOCK_SIZE_MASK, &fl, &sl);
+        EXTRACT_BLOCK(tmp_b, pool, fl, sl);
+        tmp_b->size += (b->size & BLOCK_SIZE_MASK) + BHDR_OVERHEAD;
+        b = tmp_b;
+    }
+    tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE_MASK);
+    tmp_b->prev_hdr = b;
+
+    MAPPING_INSERT(b->size & BLOCK_SIZE_MASK, &fl, &sl);
+
+    if ( (b->prev_hdr == NULL) && ((tmp_b->size & BLOCK_SIZE_MASK) == 0) )
+    {
+        pool->put_mem(b);
+        pool->num_regions--;
+        pool->used_size -= BHDR_OVERHEAD; /* sentinel block header */
+        goto out;
+    }
+
+    INSERT_BLOCK(b, pool, fl, sl);
+
+    tmp_b->size |= PREV_FREE;
+    tmp_b->prev_hdr = b;
+ out:
+    spin_unlock(&pool->lock);
+}
+
+/*
+ * Glue for xmalloc().
+ */
+
+static struct xmem_pool *xenpool;
+
+static void *xmalloc_pool_get(unsigned long size)
+{
+    ASSERT(size == PAGE_SIZE);
+    return alloc_xenheap_pages(0);
+}
+
+static void xmalloc_pool_put(void *p)
+{
+    free_xenheap_pages(p,0);
+}
+
+static void *xmalloc_whole_pages(unsigned long size)
+{
+    struct bhdr *b;
+    unsigned int pageorder = get_order_from_bytes(size + BHDR_OVERHEAD);
+
+    b = alloc_xenheap_pages(pageorder);
+    if ( b == NULL )
+        return NULL;
+
+    b->size = (1 << (pageorder + PAGE_SHIFT));
+    return (void *)b->ptr.buffer;
+}
+
+static void tlsf_init(void)
+{
+    INIT_LIST_HEAD(&pool_list_head);
+    spin_lock_init(&pool_list_lock);
+    xenpool = xmem_pool_create(
+        "xmalloc", xmalloc_pool_get, xmalloc_pool_put,
+        PAGE_SIZE, 0, PAGE_SIZE);
+    BUG_ON(!xenpool);
+}
+
+/*
+ * xmalloc()
+ */
+
+void *_xmalloc(unsigned long size, unsigned long align)
+{
+    void *p;
+    u32 pad;
+
+    ASSERT(!in_irq());
+
+    ASSERT((align & (align - 1)) == 0);
+    if ( align < MEM_ALIGN )
+        align = MEM_ALIGN;
+    size += align - MEM_ALIGN;
+
+    if ( !xenpool )
+        tlsf_init();
+
+    if ( size >= (PAGE_SIZE - (2*BHDR_OVERHEAD)) )
+        p = xmalloc_whole_pages(size);
+    else
+        p = xmem_pool_alloc(size, xenpool);
+
+    /* Add alignment padding. */
+    if ( (pad = -(long)p & (align - 1)) != 0 )
+    {
+        char *q = (char *)p + pad;
+        struct bhdr *b = (struct bhdr *)(q - BHDR_OVERHEAD);
+        ASSERT(q > (char *)p);
+        b->size = pad | 1;
+        p = q;
+    }
+
+    ASSERT(((unsigned long)p & (align - 1)) == 0);
+    return p;
+}
+
+void xfree(void *p)
+{
+    struct bhdr *b;
+
+    ASSERT(!in_irq());
+
+    if ( p == NULL )
+        return;
+
+    /* Strip alignment padding. */
+    b = (struct bhdr *)((char *) p - BHDR_OVERHEAD);
+    if ( b->size & 1 )
+    {
+        p = (char *)p - (b->size & ~1u);
+        b = (struct bhdr *)((char *)p - BHDR_OVERHEAD);
+        ASSERT(!(b->size & 1));
+    }
+
+    if ( b->size >= (PAGE_SIZE - (2*BHDR_OVERHEAD)) )
+        free_xenheap_pages((void *)b, get_order_from_bytes(b->size));
+    else
+        xmem_pool_free(p, xenpool);
+}
diff -r 6583186e5989 -r 46d7e12c4c91 xen/drivers/Makefile
--- a/xen/drivers/Makefile      Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/drivers/Makefile      Wed Oct 22 11:46:55 2008 +0900
@@ -1,6 +1,6 @@ subdir-y += char
 subdir-y += char
 subdir-y += cpufreq
 subdir-y += pci
-subdir-$(x86) += passthrough
+subdir-y += passthrough
 subdir-$(HAS_ACPI) += acpi
 subdir-$(HAS_VGA) += video
diff -r 6583186e5989 -r 46d7e12c4c91 xen/drivers/acpi/pmstat.c
--- a/xen/drivers/acpi/pmstat.c Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/drivers/acpi/pmstat.c Wed Oct 22 11:46:55 2008 +0900
@@ -52,7 +52,7 @@ int do_get_pm_info(struct xen_sysctl_get
     int ret = 0;
     const struct processor_pminfo *pmpt;
 
-    if ( (op->cpuid >= NR_CPUS) || !cpu_online(op->cpuid) )
+    if ( !op || (op->cpuid >= NR_CPUS) || !cpu_online(op->cpuid) )
         return -EINVAL;
     pmpt = processor_pminfo[op->cpuid];
 
@@ -87,7 +87,7 @@ int do_get_pm_info(struct xen_sysctl_get
         uint64_t tmp_idle_ns;
         struct pm_px *pxpt = cpufreq_statistic_data[op->cpuid];
 
-        if ( !pxpt )
+        if ( !pxpt || !pxpt->u.pt || !pxpt->u.trans_pt )
             return -ENODATA;
 
         total_idle_ns = get_cpu_idle_time(op->cpuid);
diff -r 6583186e5989 -r 46d7e12c4c91 xen/drivers/char/ns16550.c
--- a/xen/drivers/char/ns16550.c        Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/drivers/char/ns16550.c        Wed Oct 22 11:46:55 2008 +0900
@@ -18,17 +18,19 @@
 #include <asm/io.h>
 
 /*
- * Configure serial port with a string <baud>,DPS,<io-base>,<irq>.
+ * Configure serial port with a string:
+ *   <baud>[/<clock_hz>][,DPS[,<io-base>[,<irq>]]].
  * The tail of the string can be omitted if platform defaults are sufficient.
  * If the baud rate is pre-configured, perhaps by a bootloader, then 'auto'
- * can be specified in place of a numeric baud rate.
+ * can be specified in place of a numeric baud rate. Polled mode is specified
+ * by requesting irq 0.
  */
 static char opt_com1[30] = "", opt_com2[30] = "";
 string_param("com1", opt_com1);
 string_param("com2", opt_com2);
 
 static struct ns16550 {
-    int baud, data_bits, parity, stop_bits, irq;
+    int baud, clock_hz, data_bits, parity, stop_bits, irq;
     unsigned long io_base;   /* I/O port or memory-mapped I/O address. */
     char *remapped_io_base;  /* Remapped virtual address of mmap I/O.  */ 
     /* UART with IRQ line: interrupt-driven I/O. */
@@ -192,7 +194,7 @@ static void __devinit ns16550_init_preir
     if ( uart->baud != BAUD_AUTO )
     {
         /* Baud rate specified: program it into the divisor latch. */
-        divisor = UART_CLOCK_HZ / (uart->baud * 16);
+        divisor = uart->clock_hz / (uart->baud << 4);
         ns_write_reg(uart, DLL, (char)divisor);
         ns_write_reg(uart, DLM, (char)(divisor >> 8));
     }
@@ -201,7 +203,7 @@ static void __devinit ns16550_init_preir
         /* Baud rate already set: read it out from the divisor latch. */
         divisor  = ns_read_reg(uart, DLL);
         divisor |= ns_read_reg(uart, DLM) << 8;
-        uart->baud = UART_CLOCK_HZ / (divisor * 16);
+        uart->baud = uart->clock_hz / (divisor << 4);
     }
     ns_write_reg(uart, LCR, lcr);
 
@@ -354,6 +356,12 @@ static void __init ns16550_parse_port_co
     }
     else if ( (baud = simple_strtoul(conf, &conf, 10)) != 0 )
         uart->baud = baud;
+
+    if ( *conf == '/')
+    {
+        conf++;
+        uart->clock_hz = simple_strtoul(conf, &conf, 0) << 4;
+    }
 
     if ( *conf != ',' )
         goto config_parsed;
@@ -408,6 +416,7 @@ void __init ns16550_init(int index, stru
     uart->baud      = (defaults->baud ? :
                        console_has((index == 0) ? "com1" : "com2")
                        ? BAUD_AUTO : 0);
+    uart->clock_hz  = UART_CLOCK_HZ;
     uart->data_bits = defaults->data_bits;
     uart->parity    = parse_parity_char(defaults->parity);
     uart->stop_bits = defaults->stop_bits;
diff -r 6583186e5989 -r 46d7e12c4c91 xen/drivers/cpufreq/cpufreq.c
--- a/xen/drivers/cpufreq/cpufreq.c     Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/drivers/cpufreq/cpufreq.c     Wed Oct 22 11:46:55 2008 +0900
@@ -34,6 +34,7 @@
 #include <xen/sched.h>
 #include <xen/timer.h>
 #include <xen/xmalloc.h>
+#include <xen/guest_access.h>
 #include <xen/domain.h>
 #include <asm/bug.h>
 #include <asm/io.h>
@@ -185,10 +186,18 @@ int cpufreq_del_cpu(unsigned int cpu)
     return 0;
 }
 
+static void print_PCT(struct xen_pct_register *ptr)
+{
+    printk(KERN_INFO "\t_PCT: descriptor=%d, length=%d, space_id=%d, "
+            "bit_width=%d, bit_offset=%d, reserved=%d, address=%"PRId64"\n",
+            ptr->descriptor, ptr->length, ptr->space_id, ptr->bit_width, 
+            ptr->bit_offset, ptr->reserved, ptr->address);
+}
+
 static void print_PSS(struct xen_processor_px *ptr, int count)
 {
     int i;
-    printk(KERN_INFO "\t_PSS:\n");
+    printk(KERN_INFO "\t_PSS: state_count=%d\n", count);
     for (i=0; i<count; i++){
         printk(KERN_INFO "\tState%d: %"PRId64"MHz %"PRId64"mW %"PRId64"us "
                "%"PRId64"us 0x%"PRIx64" 0x%"PRIx64"\n",
@@ -211,20 +220,19 @@ static void print_PSD( struct xen_psd_pa
             ptr->num_processors);
 }
 
+static void print_PPC(unsigned int platform_limit)
+{
+    printk(KERN_INFO "\t_PPC: %d\n", platform_limit);
+}
+
 int set_px_pminfo(uint32_t acpi_id, struct xen_processor_performance 
*dom0_px_info)
 {
     int ret=0, cpuid;
     struct processor_pminfo *pmpt;
     struct processor_performance *pxpt;
 
-    if ( !(xen_processor_pmbits & XEN_PROCESSOR_PM_PX) )
-    {
-        ret = -ENOSYS;
-        goto out;
-    }
-
     cpuid = get_cpu_id(acpi_id);
-    if ( cpuid < 0 )
+    if ( cpuid < 0 || !dom0_px_info)
     {
         ret = -EINVAL;
         goto out;
@@ -256,6 +264,8 @@ int set_px_pminfo(uint32_t acpi_id, stru
         memcpy ((void *)&pxpt->status_register,
                 (void *)&dom0_px_info->status_register,
                 sizeof(struct xen_pct_register));
+        print_PCT(&pxpt->control_register);
+        print_PCT(&pxpt->status_register);
     }
     if ( dom0_px_info->flags & XEN_PX_PSS ) 
     {
@@ -265,12 +275,8 @@ int set_px_pminfo(uint32_t acpi_id, stru
             ret = -ENOMEM;
             goto out;
         }
-        if ( xenpf_copy_px_states(pxpt, dom0_px_info) )
-        {
-            xfree(pxpt->states);
-            ret = -EFAULT;
-            goto out;
-        }
+        copy_from_guest(pxpt->states, dom0_px_info->states, 
+                                      dom0_px_info->state_count);
         pxpt->state_count = dom0_px_info->state_count;
         print_PSS(pxpt->states,pxpt->state_count);
     }
@@ -285,6 +291,7 @@ int set_px_pminfo(uint32_t acpi_id, stru
     if ( dom0_px_info->flags & XEN_PX_PPC )
     {
         pxpt->platform_limit = dom0_px_info->platform_limit;
+        print_PPC(pxpt->platform_limit);
 
         if ( pxpt->init == XEN_PX_INIT )
         {
diff -r 6583186e5989 -r 46d7e12c4c91 xen/drivers/cpufreq/utility.c
--- a/xen/drivers/cpufreq/utility.c     Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/drivers/cpufreq/utility.c     Wed Oct 22 11:46:55 2008 +0900
@@ -27,6 +27,7 @@
 #include <xen/types.h>
 #include <xen/sched.h>
 #include <xen/timer.h>
+#include <xen/trace.h>
 #include <asm/config.h>
 #include <acpi/cpufreq/cpufreq.h>
 #include <public/sysctl.h>
@@ -72,27 +73,30 @@ int cpufreq_statistic_init(unsigned int 
     struct pm_px *pxpt = cpufreq_statistic_data[cpuid];
     const struct processor_pminfo *pmpt = processor_pminfo[cpuid];
 
+    if ( !pmpt )
+        return -EINVAL;
+
+    if ( pxpt )
+        return 0;
+
     count = pmpt->perf.state_count;
 
-    if ( !pmpt )
-        return -EINVAL;
-
+    pxpt = xmalloc(struct pm_px);
     if ( !pxpt )
-    {
-        pxpt = xmalloc(struct pm_px);
-        if ( !pxpt )
-            return -ENOMEM;
-        memset(pxpt, 0, sizeof(*pxpt));
-        cpufreq_statistic_data[cpuid] = pxpt;
-    }
+        return -ENOMEM;
+    memset(pxpt, 0, sizeof(*pxpt));
+    cpufreq_statistic_data[cpuid] = pxpt;
 
     pxpt->u.trans_pt = xmalloc_array(uint64_t, count * count);
-    if (!pxpt->u.trans_pt)
+    if (!pxpt->u.trans_pt) {
+        xfree(pxpt);
         return -ENOMEM;
+    }
 
     pxpt->u.pt = xmalloc_array(struct pm_px_val, count);
     if (!pxpt->u.pt) {
         xfree(pxpt->u.trans_pt);
+        xfree(pxpt);
         return -ENOMEM;
     }
 
@@ -119,7 +123,8 @@ void cpufreq_statistic_exit(unsigned int
         return;
     xfree(pxpt->u.trans_pt);
     xfree(pxpt->u.pt);
-    memset(pxpt, 0, sizeof(struct pm_px));
+    xfree(pxpt);
+    cpufreq_statistic_data[cpuid] = NULL;
 }
 
 void cpufreq_statistic_reset(unsigned int cpuid)
@@ -128,7 +133,7 @@ void cpufreq_statistic_reset(unsigned in
     struct pm_px *pxpt = cpufreq_statistic_data[cpuid];
     const struct processor_pminfo *pmpt = processor_pminfo[cpuid];
 
-    if ( !pxpt || !pmpt )
+    if ( !pmpt || !pxpt || !pxpt->u.pt || !pxpt->u.trans_pt )
         return;
 
     count = pmpt->perf.state_count;
@@ -293,7 +298,13 @@ int __cpufreq_driver_target(struct cpufr
     int retval = -EINVAL;
 
     if (cpu_online(policy->cpu) && cpufreq_driver->target)
+    {
+        unsigned int prev_freq = policy->cur;
+
         retval = cpufreq_driver->target(policy, target_freq, relation);
+        if ( retval == 0 )
+            TRACE_2D(TRC_PM_FREQ_CHANGE, prev_freq/1000, policy->cur/1000);
+    }
 
     return retval;
 }
diff -r 6583186e5989 -r 46d7e12c4c91 xen/drivers/passthrough/Makefile
--- a/xen/drivers/passthrough/Makefile  Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/drivers/passthrough/Makefile  Wed Oct 22 11:46:55 2008 +0900
@@ -1,4 +1,5 @@ subdir-$(x86) += vtd
 subdir-$(x86) += vtd
+subdir-$(ia64) += vtd
 subdir-$(x86) += amd
 
 obj-y += iommu.o
diff -r 6583186e5989 -r 46d7e12c4c91 xen/drivers/passthrough/io.c
--- a/xen/drivers/passthrough/io.c      Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/drivers/passthrough/io.c      Wed Oct 22 11:46:55 2008 +0900
@@ -20,6 +20,9 @@
 
 #include <xen/event.h>
 #include <xen/iommu.h>
+#include <asm/hvm/irq.h>
+#include <asm/hvm/iommu.h>
+#include <xen/hvm/irq.h>
 
 static void pt_irq_time_out(void *data)
 {
@@ -245,6 +248,7 @@ int hvm_do_IRQ_dpci(struct domain *d, un
     return 1;
 }
 
+#ifdef SUPPORT_MSI_REMAPPING
 void hvm_dpci_msi_eoi(struct domain *d, int vector)
 {
     struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
@@ -278,6 +282,63 @@ void hvm_dpci_msi_eoi(struct domain *d, 
     spin_unlock(&d->event_lock);
 }
 
+extern int vmsi_deliver(struct domain *d, int pirq);
+static int hvm_pci_msi_assert(struct domain *d, int pirq)
+{
+    return vmsi_deliver(d, pirq);
+}
+#endif
+
+void hvm_dirq_assist(struct vcpu *v)
+{
+    unsigned int irq;
+    uint32_t device, intx;
+    struct domain *d = v->domain;
+    struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
+    struct dev_intx_gsi_link *digl;
+
+    if ( !iommu_enabled || (v->vcpu_id != 0) || (hvm_irq_dpci == NULL) )
+        return;
+
+    for ( irq = find_first_bit(hvm_irq_dpci->dirq_mask, NR_IRQS);
+          irq < NR_IRQS;
+          irq = find_next_bit(hvm_irq_dpci->dirq_mask, NR_IRQS, irq + 1) )
+    {
+        if ( !test_and_clear_bit(irq, &hvm_irq_dpci->dirq_mask) )
+            continue;
+
+        spin_lock(&d->event_lock);
+#ifdef SUPPORT_MSI_REMAPPING
+        if ( test_bit(_HVM_IRQ_DPCI_MSI, &hvm_irq_dpci->mirq[irq].flags) )
+        {
+            hvm_pci_msi_assert(d, irq);
+            spin_unlock(&d->event_lock);
+            continue;
+        }
+#endif
+        stop_timer(&hvm_irq_dpci->hvm_timer[domain_irq_to_vector(d, irq)]);
+
+        list_for_each_entry ( digl, &hvm_irq_dpci->mirq[irq].digl_list, list )
+        {
+            device = digl->device;
+            intx = digl->intx;
+            hvm_pci_intx_assert(d, device, intx);
+            hvm_irq_dpci->mirq[irq].pending++;
+        }
+
+        /*
+         * Set a timer to see if the guest can finish the interrupt or not. For
+         * example, the guest OS may unmask the PIC during boot, before the
+         * guest driver is loaded. hvm_pci_intx_assert() may succeed, but the
+         * guest will never deal with the irq, then the physical interrupt line
+         * will never be deasserted.
+         */
+        set_timer(&hvm_irq_dpci->hvm_timer[domain_irq_to_vector(d, irq)],
+                  NOW() + PT_IRQ_TIME_OUT);
+        spin_unlock(&d->event_lock);
+    }
+}
+
 void hvm_dpci_eoi(struct domain *d, unsigned int guest_gsi,
                   union vioapic_redir_entry *ent)
 {
diff -r 6583186e5989 -r 46d7e12c4c91 xen/drivers/passthrough/iommu.c
--- a/xen/drivers/passthrough/iommu.c   Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/drivers/passthrough/iommu.c   Wed Oct 22 11:46:55 2008 +0900
@@ -19,8 +19,6 @@
 #include <xen/paging.h>
 #include <xen/guest_access.h>
 
-extern struct iommu_ops intel_iommu_ops;
-extern struct iommu_ops amd_iommu_ops;
 static void parse_iommu_param(char *s);
 static int iommu_populate_page_table(struct domain *d);
 int intel_vtd_setup(void);
diff -r 6583186e5989 -r 46d7e12c4c91 xen/drivers/passthrough/pci.c
--- a/xen/drivers/passthrough/pci.c     Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/drivers/passthrough/pci.c     Wed Oct 22 11:46:55 2008 +0900
@@ -21,6 +21,8 @@
 #include <xen/list.h>
 #include <xen/prefetch.h>
 #include <xen/iommu.h>
+#include <asm/hvm/iommu.h>
+#include <asm/hvm/irq.h>
 #include <xen/delay.h>
 #include <xen/keyhandler.h>
 
@@ -207,6 +209,7 @@ void pci_release_devices(struct domain *
     }
 }
 
+#ifdef SUPPORT_MSI_REMAPPING
 static void dump_pci_devices(unsigned char ch)
 {
     struct pci_dev *pdev;
@@ -236,7 +239,7 @@ static int __init setup_dump_pcidevs(voi
     return 0;
 }
 __initcall(setup_dump_pcidevs);
-
+#endif
 
 
 /*
diff -r 6583186e5989 -r 46d7e12c4c91 xen/drivers/passthrough/vtd/Makefile
--- a/xen/drivers/passthrough/vtd/Makefile      Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/drivers/passthrough/vtd/Makefile      Wed Oct 22 11:46:55 2008 +0900
@@ -1,4 +1,5 @@ subdir-$(x86) += x86
 subdir-$(x86) += x86
+subdir-$(ia64) += ia64
 
 obj-y += iommu.o
 obj-y += dmar.o
diff -r 6583186e5989 -r 46d7e12c4c91 xen/drivers/passthrough/vtd/ia64/Makefile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/drivers/passthrough/vtd/ia64/Makefile Wed Oct 22 11:46:55 2008 +0900
@@ -0,0 +1,1 @@
+obj-y += vtd.o
diff -r 6583186e5989 -r 46d7e12c4c91 xen/drivers/passthrough/vtd/ia64/vtd.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/drivers/passthrough/vtd/ia64/vtd.c    Wed Oct 22 11:46:55 2008 +0900
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2008, 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.
+ *
+ * Copyright (C) Allen Kay <allen.m.kay@xxxxxxxxx>
+ * Copyright (C) Weidong Han <weidong.han@xxxxxxxxx>
+ */
+
+#include <xen/sched.h>
+#include <xen/domain_page.h>
+#include <xen/iommu.h>
+#include <asm/xensystem.h>
+#include <asm/sal.h>
+#include "../iommu.h"
+#include "../dmar.h"
+#include "../vtd.h"
+
+
+int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1};
+/* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */
+u8 irq_vector[NR_IRQ_VECTORS] __read_mostly;
+
+void *map_vtd_domain_page(u64 maddr)
+{
+    return (void *)((u64)map_domain_page(maddr >> PAGE_SHIFT) |
+            (maddr & (PAGE_SIZE - PAGE_SIZE_4K)));
+}
+
+void unmap_vtd_domain_page(void *va)
+{
+    unmap_domain_page(va);
+}
+
+/* Allocate page table, return its machine address */
+u64 alloc_pgtable_maddr(void)
+{
+    struct page_info *pg;
+    u64 *vaddr;
+
+    pg = alloc_domheap_page(NULL, 0);
+    vaddr = map_domain_page(page_to_mfn(pg));
+    if ( !vaddr )
+        return 0;
+    memset(vaddr, 0, PAGE_SIZE);
+
+    iommu_flush_cache_page(vaddr);
+    unmap_domain_page(vaddr);
+
+    return page_to_maddr(pg);
+}
+
+void free_pgtable_maddr(u64 maddr)
+{
+    if ( maddr != 0 )
+        free_domheap_page(maddr_to_page(maddr));
+}
+
+unsigned int get_cache_line_size(void)
+{
+    return L1_CACHE_BYTES;
+}
+
+void cacheline_flush(char * addr)
+{
+    ia64_fc(addr);
+    ia64_sync_i();
+    ia64_srlz_i();
+}
+
+void flush_all_cache()
+{
+    ia64_sal_cache_flush(3);
+}
+
+void * map_to_nocache_virt(int nr_iommus, u64 maddr)
+{
+  return (void *) ( maddr + __IA64_UNCACHED_OFFSET);
+}
+
+struct hvm_irq_dpci *domain_get_irq_dpci(struct domain *domain)
+{
+    if ( !domain )
+        return NULL;
+
+    return domain->arch.hvm_domain.irq.dpci;
+}
+
+int domain_set_irq_dpci(struct domain *domain, struct hvm_irq_dpci *dpci)
+{
+    if ( !domain || !dpci )
+        return 0;
+
+    domain->arch.hvm_domain.irq.dpci = dpci;
+    return 1;
+}
+
+void hvm_dpci_isairq_eoi(struct domain *d, unsigned int isairq)
+{
+    /* dummy */
+}
diff -r 6583186e5989 -r 46d7e12c4c91 xen/drivers/passthrough/vtd/intremap.c
--- a/xen/drivers/passthrough/vtd/intremap.c    Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/drivers/passthrough/vtd/intremap.c    Wed Oct 22 11:46:55 2008 +0900
@@ -21,6 +21,7 @@
 #include <xen/irq.h>
 #include <xen/sched.h>
 #include <xen/iommu.h>
+#include <asm/hvm/iommu.h>
 #include <xen/time.h>
 #include <xen/pci.h>
 #include <xen/pci_regs.h>
@@ -128,7 +129,13 @@ static int ioapic_rte_to_remap_entry(str
     memcpy(&new_ire, iremap_entry, sizeof(struct iremap_entry));
 
     if ( rte_upper )
+    {
+#if defined(__i386__) || defined(__x86_64__)
         new_ire.lo.dst = (value >> 24) << 8;
+#else /* __ia64__ */
+        new_ire.lo.dst = value >> 16;
+#endif
+    }
     else
     {
         *(((u32 *)&new_rte) + 0) = value;
@@ -179,7 +186,7 @@ unsigned int io_apic_read_remap_rte(
     struct IO_xAPIC_route_entry old_rte = { 0 };
     struct IO_APIC_route_remap_entry *remap_rte;
     int rte_upper = (reg & 1) ? 1 : 0;
-    struct iommu *iommu = ioapic_to_iommu(mp_ioapics[apic].mpc_apicid);
+    struct iommu *iommu = ioapic_to_iommu(IO_APIC_ID(apic));
     struct ir_ctrl *ir_ctrl = iommu_ir_ctrl(iommu);
 
     if ( !iommu || !ir_ctrl || ir_ctrl->iremap_maddr == 0 ||
@@ -224,7 +231,7 @@ void io_apic_write_remap_rte(
     struct IO_xAPIC_route_entry old_rte = { 0 };
     struct IO_APIC_route_remap_entry *remap_rte;
     unsigned int rte_upper = (reg & 1) ? 1 : 0;
-    struct iommu *iommu = ioapic_to_iommu(mp_ioapics[apic].mpc_apicid);
+    struct iommu *iommu = ioapic_to_iommu(IO_APIC_ID(apic));
     struct ir_ctrl *ir_ctrl = iommu_ir_ctrl(iommu);
     int saved_mask;
 
@@ -253,7 +260,7 @@ void io_apic_write_remap_rte(
     *(IO_APIC_BASE(apic)+4) = *(((int *)&old_rte)+0);
     remap_rte->mask = saved_mask;
 
-    if ( ioapic_rte_to_remap_entry(iommu, mp_ioapics[apic].mpc_apicid,
+    if ( ioapic_rte_to_remap_entry(iommu, IO_APIC_ID(apic),
                                    &old_rte, rte_upper, value) )
     {
         *IO_APIC_BASE(apic) = rte_upper ? (reg + 1) : reg;
@@ -328,7 +335,8 @@ static int remap_entry_to_msi_msg(
 }
 
 static int msi_msg_to_remap_entry(
-    struct iommu *iommu, struct pci_dev *pdev, struct msi_msg *msg)
+    struct iommu *iommu, struct pci_dev *pdev,
+    struct msi_desc *msi_desc, struct msi_msg *msg)
 {
     struct iremap_entry *iremap_entry = NULL, *iremap_entries;
     struct iremap_entry new_ire;
@@ -336,32 +344,18 @@ static int msi_msg_to_remap_entry(
     unsigned int index;
     unsigned long flags;
     struct ir_ctrl *ir_ctrl = iommu_ir_ctrl(iommu);
-    int i = 0;
 
     remap_rte = (struct msi_msg_remap_entry *) msg;
     spin_lock_irqsave(&ir_ctrl->iremap_lock, flags);
 
-    iremap_entries =
-        (struct iremap_entry *)map_vtd_domain_page(ir_ctrl->iremap_maddr);
-
-    /* If the entry for a PCI device has been there, use the old entry,
-     * Or, assign a new entry for it.
-     */
-    for ( i = 0; i <= ir_ctrl->iremap_index; i++ )
-    {
-        iremap_entry = &iremap_entries[i];
-        if ( iremap_entry->hi.sid ==
-             ((pdev->bus << 8) | pdev->devfn) )
-           break;
-    }
-
-    if ( i > ir_ctrl->iremap_index )
-    {
-       ir_ctrl->iremap_index++;
+    if ( msi_desc->remap_index < 0 )
+    {
+        ir_ctrl->iremap_index++;
         index = ir_ctrl->iremap_index;
+        msi_desc->remap_index = index;
     }
     else
-        index = i;
+        index = msi_desc->remap_index;
 
     if ( index > IREMAP_ENTRY_NR - 1 )
     {
@@ -369,11 +363,13 @@ static int msi_msg_to_remap_entry(
                 "%s: intremap index (%d) is larger than"
                 " the maximum index (%ld)!\n",
                 __func__, index, IREMAP_ENTRY_NR - 1);
-        unmap_vtd_domain_page(iremap_entries);
+        msi_desc->remap_index = -1;
         spin_unlock_irqrestore(&ir_ctrl->iremap_lock, flags);
         return -EFAULT;
     }
 
+    iremap_entries =
+        (struct iremap_entry *)map_vtd_domain_page(ir_ctrl->iremap_maddr);
     iremap_entry = &iremap_entries[index];
     memcpy(&new_ire, iremap_entry, sizeof(struct iremap_entry));
 
@@ -450,7 +446,7 @@ void msi_msg_write_remap_rte(
     if ( !iommu || !ir_ctrl || ir_ctrl->iremap_maddr == 0 )
         return;
 
-    msi_msg_to_remap_entry(iommu, pdev, msg);
+    msi_msg_to_remap_entry(iommu, pdev, msi_desc, msg);
 }
 #elif defined(__ia64__)
 void msi_msg_read_remap_rte(
@@ -482,7 +478,7 @@ int intremap_setup(struct iommu *iommu)
         {
             dprintk(XENLOG_WARNING VTDPREFIX,
                     "Cannot allocate memory for ir_ctrl->iremap_maddr\n");
-            return -ENODEV;
+            return -ENOMEM;
         }
         ir_ctrl->iremap_index = -1;
     }
@@ -490,10 +486,10 @@ int intremap_setup(struct iommu *iommu)
 #if defined(ENABLED_EXTENDED_INTERRUPT_SUPPORT)
     /* set extended interrupt mode bit */
     ir_ctrl->iremap_maddr |=
-            ecap_ext_intr(iommu->ecap) ? (1 << IRTA_REG_EIMI_SHIFT) : 0;
+            ecap_ext_intr(iommu->ecap) ? (1 << IRTA_REG_EIME_SHIFT) : 0;
 #endif
-    /* size field = 256 entries per 4K page = 8 - 1 */
-    ir_ctrl->iremap_maddr |= 7;
+    /* set size of the interrupt remapping table */ 
+    ir_ctrl->iremap_maddr |= IRTA_REG_TABLE_SIZE;
     dmar_writeq(iommu->reg, DMAR_IRTA_REG, ir_ctrl->iremap_maddr);
 
     /* set SIRTP */
diff -r 6583186e5989 -r 46d7e12c4c91 xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c       Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/drivers/passthrough/vtd/iommu.c       Wed Oct 22 11:46:55 2008 +0900
@@ -24,6 +24,7 @@
 #include <xen/xmalloc.h>
 #include <xen/domain_page.h>
 #include <xen/iommu.h>
+#include <asm/hvm/iommu.h>
 #include <xen/numa.h>
 #include <xen/time.h>
 #include <xen/pci.h>
@@ -218,10 +219,10 @@ static u64 addr_to_dma_page_maddr(struct
             if ( !alloc )
                 break;
             maddr = alloc_pgtable_maddr();
+            if ( !maddr )
+                break;
             dma_set_pte_addr(*pte, maddr);
             vaddr = map_vtd_domain_page(maddr);
-            if ( !vaddr )
-                break;
 
             /*
              * high level table always sets r/w, last level
@@ -234,8 +235,6 @@ static u64 addr_to_dma_page_maddr(struct
         else
         {
             vaddr = map_vtd_domain_page(pte->val);
-            if ( !vaddr )
-                break;
         }
 
         if ( level == 2 )
@@ -567,26 +566,6 @@ static void dma_pte_clear_one(struct dom
     }
 
     unmap_vtd_domain_page(page);
-}
-
-/* clear last level pte, a tlb flush should be followed */
-static void dma_pte_clear_range(struct domain *domain, u64 start, u64 end)
-{
-    struct hvm_iommu *hd = domain_hvm_iommu(domain);
-    int addr_width = agaw_to_width(hd->agaw);
-
-    start &= (((u64)1) << addr_width) - 1;
-    end &= (((u64)1) << addr_width) - 1;
-    /* in case it's partial page */
-    start = PAGE_ALIGN_4K(start);
-    end &= PAGE_MASK_4K;
-
-    /* we don't need lock here, nobody else touches the iova range */
-    while ( start < end )
-    {
-        dma_pte_clear_one(domain, start);
-        start += PAGE_SIZE_4K;
-    }
 }
 
 static void iommu_free_pagetable(u64 pt_maddr, int level)
@@ -877,6 +856,7 @@ static void dma_msi_data_init(struct iom
     spin_unlock_irqrestore(&iommu->register_lock, flags);
 }
 
+#ifdef SUPPORT_MSI_REMAPPING
 static void dma_msi_addr_init(struct iommu *iommu, int phy_cpu)
 {
     u64 msi_address;
@@ -893,6 +873,12 @@ static void dma_msi_addr_init(struct iom
     dmar_writel(iommu->reg, DMAR_FEUADDR_REG, (u32)(msi_address >> 32));
     spin_unlock_irqrestore(&iommu->register_lock, flags);
 }
+#else
+static void dma_msi_addr_init(struct iommu *iommu, int phy_cpu)
+{
+    /* ia64: TODO */
+}
+#endif
 
 static void dma_msi_set_affinity(unsigned int vector, cpumask_t dest)
 {
@@ -1024,7 +1010,7 @@ static int intel_iommu_domain_init(struc
 {
     struct hvm_iommu *hd = domain_hvm_iommu(d);
     struct iommu *iommu = NULL;
-    u64 i;
+    u64 i, j, tmp;
     struct acpi_drhd_unit *drhd;
 
     drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list);
@@ -1043,11 +1029,13 @@ static int intel_iommu_domain_init(struc
          */
         for ( i = 0; i < max_page; i++ )
         {
-            if ( xen_in_range(i << PAGE_SHIFT_4K, (i + 1) << PAGE_SHIFT_4K) ||
-                 tboot_in_range(i << PAGE_SHIFT_4K, (i + 1) << PAGE_SHIFT_4K) )
+            if ( xen_in_range(i << PAGE_SHIFT, (i + 1) << PAGE_SHIFT) ||
+                 tboot_in_range(i << PAGE_SHIFT, (i + 1) << PAGE_SHIFT) )
                 continue;
 
-            iommu_map_page(d, i, i);
+            tmp = 1 << (PAGE_SHIFT - PAGE_SHIFT_4K);
+            for ( j = 0; j < tmp; j++ )
+                iommu_map_page(d, (i*tmp+j), (i*tmp+j));
         }
 
         setup_dom0_devices(d);
@@ -1511,75 +1499,26 @@ int intel_iommu_unmap_page(struct domain
     return 0;
 }
 
-int iommu_page_mapping(struct domain *domain, paddr_t iova,
-                       paddr_t hpa, size_t size, int prot)
-{
-    struct hvm_iommu *hd = domain_hvm_iommu(domain);
-    struct acpi_drhd_unit *drhd;
-    struct iommu *iommu;
-    u64 start_pfn, end_pfn;
-    struct dma_pte *page = NULL, *pte = NULL;
-    int index;
-    u64 pg_maddr;
-
-    if ( (prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0 )
-        return -EINVAL;
-
-    iova = (iova >> PAGE_SHIFT_4K) << PAGE_SHIFT_4K;
-    start_pfn = hpa >> PAGE_SHIFT_4K;
-    end_pfn = (PAGE_ALIGN_4K(hpa + size)) >> PAGE_SHIFT_4K;
-    index = 0;
-    while ( start_pfn < end_pfn )
-    {
-        pg_maddr = addr_to_dma_page_maddr(domain, iova + PAGE_SIZE_4K*index, 
1);
-        if ( pg_maddr == 0 )
-            return -ENOMEM;
-        page = (struct dma_pte *)map_vtd_domain_page(pg_maddr);
-        pte = page + (start_pfn & LEVEL_MASK);
-        dma_set_pte_addr(*pte, (paddr_t)start_pfn << PAGE_SHIFT_4K);
-        dma_set_pte_prot(*pte, prot);
-        iommu_flush_cache_entry(pte);
-        unmap_vtd_domain_page(page);
-        start_pfn++;
-        index++;
-    }
-
-    if ( index > 0 )
-    {
-        for_each_drhd_unit ( drhd )
-        {
-            iommu = drhd->iommu;
-            if ( test_bit(iommu->index, &hd->iommu_bitmap) )
-                if ( iommu_flush_iotlb_psi(iommu, domain_iommu_domid(domain),
-                                           iova, index, 1))
-                    iommu_flush_write_buffer(iommu);
-        }
-    }
-
-    return 0;
-}
-
-int iommu_page_unmapping(struct domain *domain, paddr_t addr, size_t size)
-{
-    dma_pte_clear_range(domain, addr, addr + size);
-
-    return 0;
-}
-
 static int iommu_prepare_rmrr_dev(struct domain *d,
                                   struct acpi_rmrr_unit *rmrr,
                                   u8 bus, u8 devfn)
 {
-    u64 size;
-    int ret;
-
-    /* page table init */
-    size = rmrr->end_address - rmrr->base_address + 1;
-    ret = iommu_page_mapping(d, rmrr->base_address,
-                             rmrr->base_address, size,
-                             DMA_PTE_READ|DMA_PTE_WRITE);
-    if ( ret )
-        return ret;
+    int ret = 0;
+    u64 base, end;
+    unsigned long base_pfn, end_pfn;
+
+    ASSERT(rmrr->base_address < rmrr->end_address);
+    
+    base = rmrr->base_address & PAGE_MASK_4K;
+    base_pfn = base >> PAGE_SHIFT_4K;
+    end = PAGE_ALIGN_4K(rmrr->end_address);
+    end_pfn = end >> PAGE_SHIFT_4K;
+
+    while ( base_pfn < end_pfn )
+    {
+        intel_iommu_map_page(d, base_pfn, base_pfn);
+        base_pfn++;
+    }
 
     if ( domain_context_mapped(bus, devfn) == 0 )
         ret = domain_context_mapping(d, bus, devfn);
diff -r 6583186e5989 -r 46d7e12c4c91 xen/drivers/passthrough/vtd/qinval.c
--- a/xen/drivers/passthrough/vtd/qinval.c      Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/drivers/passthrough/vtd/qinval.c      Wed Oct 22 11:46:55 2008 +0900
@@ -428,7 +428,11 @@ int qinval_setup(struct iommu *iommu)
     {
         qi_ctrl->qinval_maddr = alloc_pgtable_maddr();
         if ( qi_ctrl->qinval_maddr == 0 )
-            panic("Cannot allocate memory for qi_ctrl->qinval_maddr\n");
+        {
+            dprintk(XENLOG_WARNING VTDPREFIX,
+                    "Cannot allocate memory for qi_ctrl->qinval_maddr\n");
+            return -ENOMEM;
+        }
         flush->context = flush_context_qi;
         flush->iotlb = flush_iotlb_qi;
     }
diff -r 6583186e5989 -r 46d7e12c4c91 xen/drivers/passthrough/vtd/utils.c
--- a/xen/drivers/passthrough/vtd/utils.c       Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/drivers/passthrough/vtd/utils.c       Wed Oct 22 11:46:55 2008 +0900
@@ -204,6 +204,7 @@ void print_vtd_entries(struct iommu *iom
 
 void dump_iommu_info(unsigned char key)
 {
+#if defined(__i386__) || defined(__x86_64__)
     struct acpi_drhd_unit *drhd;
     struct iommu *iommu;
     int i;
@@ -305,6 +306,10 @@ void dump_iommu_info(unsigned char key)
             }
         }
     }
+#else
+    printk("%s: not implemnted on IA64 for now.\n", __func__);
+    /* ia64: TODO */
+#endif
 }
 
 /*
diff -r 6583186e5989 -r 46d7e12c4c91 xen/drivers/passthrough/vtd/x86/vtd.c
--- a/xen/drivers/passthrough/vtd/x86/vtd.c     Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/drivers/passthrough/vtd/x86/vtd.c     Wed Oct 22 11:46:55 2008 +0900
@@ -41,17 +41,19 @@ u64 alloc_pgtable_maddr(void)
 {
     struct page_info *pg;
     u64 *vaddr;
+    unsigned long mfn;
 
     pg = alloc_domheap_page(NULL, 0);
-    vaddr = map_domain_page(page_to_mfn(pg));
-    if ( !vaddr )
+    if ( !pg )
         return 0;
+    mfn = page_to_mfn(pg);
+    vaddr = map_domain_page(mfn);
     memset(vaddr, 0, PAGE_SIZE);
 
     iommu_flush_cache_page(vaddr);
     unmap_domain_page(vaddr);
 
-    return page_to_maddr(pg);
+    return (u64)mfn << PAGE_SHIFT_4K;
 }
 
 void free_pgtable_maddr(u64 maddr)
diff -r 6583186e5989 -r 46d7e12c4c91 xen/include/acpi/cpufreq/processor_perf.h
--- a/xen/include/acpi/cpufreq/processor_perf.h Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/include/acpi/cpufreq/processor_perf.h Wed Oct 22 11:46:55 2008 +0900
@@ -60,8 +60,5 @@ struct pm_px {
 
 extern struct pm_px *cpufreq_statistic_data[NR_CPUS];
 
-int xenpf_copy_px_states(struct processor_performance *pxpt,
-        struct xen_processor_performance *dom0_px_info);
-
 int cpufreq_cpu_init(unsigned int cpuid);
 #endif /* __XEN_PROCESSOR_PM_H__ */
diff -r 6583186e5989 -r 46d7e12c4c91 
xen/include/asm-ia64/linux-xen/asm/spinlock.h
--- a/xen/include/asm-ia64/linux-xen/asm/spinlock.h     Wed Oct 22 11:38:22 
2008 +0900
+++ b/xen/include/asm-ia64/linux-xen/asm/spinlock.h     Wed Oct 22 11:46:55 
2008 +0900
@@ -27,25 +27,16 @@ typedef struct {
 #ifdef DEBUG_SPINLOCK
        void *locker;
 #endif
+} raw_spinlock_t;
+
 #ifdef XEN
-       unsigned char recurse_cpu;
-       unsigned char recurse_cnt;
-#endif
-} spinlock_t;
-
-#ifdef XEN
-#ifdef DEBUG_SPINLOCK
-#define SPIN_LOCK_UNLOCKED     /*(spinlock_t)*/ { 0, NULL, -1, 0 }
-#else
-#define SPIN_LOCK_UNLOCKED     /*(spinlock_t)*/ { 0, -1, 0 }
-#endif
-static inline void spin_lock_init(spinlock_t *lock)
-{
-       *lock = ((spinlock_t)SPIN_LOCK_UNLOCKED);
-}
-#else
-#define SPIN_LOCK_UNLOCKED                     /*(spinlock_t)*/ { 0 }
-#define spin_lock_init(x)                      ((x)->lock = 0)
+#ifdef DEBUG_SPINLOCK
+#define _RAW_SPIN_LOCK_UNLOCKED        /*(raw_spinlock_t)*/ { 0, NULL }
+#else
+#define _RAW_SPIN_LOCK_UNLOCKED        /*(raw_spinlock_t)*/ { 0 }
+#endif
+#else
+#define _RAW_SPIN_LOCK_UNLOCKED        /*(raw_spinlock_t)*/ { 0 }
 #endif
 
 #ifdef ASM_SUPPORTED
@@ -59,7 +50,7 @@ static inline void spin_lock_init(spinlo
 #define IA64_SPINLOCK_CLOBBERS "ar.ccv", "ar.pfs", "p14", "p15", "r27", "r28", 
"r29", "r30", "b6", "memory"
 
 static inline void
-_raw_spin_lock_flags (spinlock_t *lock, unsigned long flags)
+_raw_spin_lock_flags (raw_spinlock_t *lock, unsigned long flags)
 {
        register volatile unsigned int *ptr asm ("r31") = &lock->lock;
 
@@ -136,10 +127,9 @@ do {                                                       
                                \
 } while (0)
 #endif /* !ASM_SUPPORTED */
 
-#define spin_is_locked(x)      ((x)->lock != 0)
-#define _raw_spin_unlock(x)    do { barrier(); ((spinlock_t *) x)->lock = 0; } 
while (0)
+#define _raw_spin_is_locked(x) ((x)->lock != 0)
+#define _raw_spin_unlock(x)    do { barrier(); (x)->lock = 0; } while (0)
 #define _raw_spin_trylock(x)   (cmpxchg_acq(&(x)->lock, 0, 1) == 0)
-#define spin_unlock_wait(x)    do { barrier(); } while ((x)->lock)
 
 typedef struct {
        volatile unsigned int read_counter      : 31;
@@ -147,16 +137,12 @@ typedef struct {
 #ifdef CONFIG_PREEMPT
        unsigned int break_lock;
 #endif
-} rwlock_t;
-#define RW_LOCK_UNLOCKED /*(rwlock_t)*/ { 0, 0 }
-
-#define rwlock_init(x)         do { *(x) = (rwlock_t) RW_LOCK_UNLOCKED; } 
while(0)
-#define read_can_lock(rw)      (*(volatile int *)(rw) >= 0)
-#define write_can_lock(rw)     (*(volatile int *)(rw) == 0)
+} raw_rwlock_t;
+#define _RAW_RW_LOCK_UNLOCKED /*(raw_rwlock_t)*/ { 0, 0 }
 
 #define _raw_read_lock(rw)                                                     
        \
 do {                                                                           
        \
-       rwlock_t *__read_lock_ptr = (rw);                                       
        \
+       raw_rwlock_t *__read_lock_ptr = (rw);                                   
        \
                                                                                
        \
        while (unlikely(ia64_fetchadd(1, (int *) __read_lock_ptr, acq) < 0)) {  
        \
                ia64_fetchadd(-1, (int *) __read_lock_ptr, rel);                
        \
@@ -167,7 +153,7 @@ do {                                                        
                                \
 
 #define _raw_read_unlock(rw)                                   \
 do {                                                           \
-       rwlock_t *__read_lock_ptr = (rw);                       \
+       raw_rwlock_t *__read_lock_ptr = (rw);                   \
        ia64_fetchadd(-1, (int *) __read_lock_ptr, rel);        \
 } while (0)
 
@@ -230,7 +216,4 @@ do {                                                        
                        \
        clear_bit(31, (x));                                                     
        \
 })
 
-#ifdef XEN
-#include <asm/xenspinlock.h>
-#endif
 #endif /*  _ASM_IA64_SPINLOCK_H */
diff -r 6583186e5989 -r 46d7e12c4c91 xen/include/asm-ia64/xenspinlock.h
--- a/xen/include/asm-ia64/xenspinlock.h        Wed Oct 22 11:38:22 2008 +0900
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-#ifndef _ASM_IA64_XENSPINLOCK_H
-#define _ASM_IA64_XENSPINLOCK_H
-
-/*
- * spin_[un]lock_recursive(): Use these forms when the lock can (safely!) be
- * reentered recursively on the same CPU. All critical regions that may form
- * part of a recursively-nested set must be protected by these forms. If there
- * are any critical regions that cannot form part of such a set, they can use
- * standard spin_[un]lock().
- */
-#define _raw_spin_lock_recursive(_lock)            \
-    do {                                           \
-        int cpu = smp_processor_id();              \
-        if ( likely((_lock)->recurse_cpu != cpu) ) \
-        {                                          \
-            spin_lock(_lock);                      \
-            (_lock)->recurse_cpu = cpu;            \
-        }                                          \
-        (_lock)->recurse_cnt++;                    \
-    } while ( 0 )
-
-#define _raw_spin_unlock_recursive(_lock)          \
-    do {                                           \
-        if ( likely(--(_lock)->recurse_cnt == 0) ) \
-        {                                          \
-            (_lock)->recurse_cpu = -1;             \
-            spin_unlock(_lock);                    \
-        }                                          \
-    } while ( 0 )
-#endif /*  _ASM_IA64_XENSPINLOCK_H */
diff -r 6583186e5989 -r 46d7e12c4c91 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/include/asm-x86/domain.h      Wed Oct 22 11:46:55 2008 +0900
@@ -250,6 +250,8 @@ struct arch_domain
     bool_t is_32bit_pv;
     /* Is shared-info page in 32-bit format? */
     bool_t has_32bit_shinfo;
+    /* Domain cannot handle spurious page faults? */
+    bool_t suppress_spurious_page_faults;
 
     /* Continuable domain_relinquish_resources(). */
     enum {
diff -r 6583186e5989 -r 46d7e12c4c91 xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h     Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/include/asm-x86/hvm/hvm.h     Wed Oct 22 11:46:55 2008 +0900
@@ -128,6 +128,7 @@ struct hvm_function_table {
     int (*msr_write_intercept)(struct cpu_user_regs *regs);
     void (*invlpg_intercept)(unsigned long vaddr);
     void (*set_uc_mode)(struct vcpu *v);
+    void (*set_info_guest)(struct vcpu *v);
 };
 
 extern struct hvm_function_table hvm_funcs;
@@ -314,4 +315,10 @@ int hvm_virtual_to_linear_addr(
     unsigned int addr_size,
     unsigned long *linear_addr);
 
+static inline void hvm_set_info_guest(struct vcpu *v)
+{
+    if ( hvm_funcs.set_info_guest )
+        return hvm_funcs.set_info_guest(v);
+}
+
 #endif /* __ASM_X86_HVM_HVM_H__ */
diff -r 6583186e5989 -r 46d7e12c4c91 xen/include/asm-x86/hvm/irq.h
--- a/xen/include/asm-x86/hvm/irq.h     Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/include/asm-x86/hvm/irq.h     Wed Oct 22 11:46:55 2008 +0900
@@ -22,62 +22,11 @@
 #ifndef __ASM_X86_HVM_IRQ_H__
 #define __ASM_X86_HVM_IRQ_H__
 
-#include <xen/types.h>
-#include <xen/spinlock.h>
-#include <asm/irq.h>
 #include <asm/pirq.h>
+#include <xen/hvm/irq.h>
 #include <asm/hvm/hvm.h>
 #include <asm/hvm/vpic.h>
 #include <asm/hvm/vioapic.h>
-#include <public/hvm/save.h>
-
-struct dev_intx_gsi_link {
-    struct list_head list;
-    uint8_t device;
-    uint8_t intx;
-    uint8_t gsi;
-    uint8_t link;
-};
-
-#define _HVM_IRQ_DPCI_MSI  0x1
-
-struct hvm_gmsi_info {
-    uint32_t gvec;
-    uint32_t gflags;
-};
-
-struct hvm_mirq_dpci_mapping {
-    uint32_t flags;
-    int pending;
-    struct list_head digl_list;
-    struct domain *dom;
-    struct hvm_gmsi_info gmsi;
-};
-
-struct hvm_girq_dpci_mapping {
-    uint8_t valid;
-    uint8_t device;
-    uint8_t intx;
-    uint8_t machine_gsi;
-};
-
-#define NR_ISAIRQS  16
-#define NR_LINK     4
-/* Protected by domain's event_lock */
-struct hvm_irq_dpci {
-    /* Machine IRQ to guest device/intx mapping. */
-    DECLARE_BITMAP(mapping, NR_PIRQS);
-    struct hvm_mirq_dpci_mapping mirq[NR_IRQS];
-    /* Guest IRQ to guest device/intx mapping. */
-    struct hvm_girq_dpci_mapping girq[NR_IRQS];
-    uint8_t msi_gvec_pirq[NR_VECTORS];
-    DECLARE_BITMAP(dirq_mask, NR_IRQS);
-    /* Record of mapped ISA IRQs */
-    DECLARE_BITMAP(isairq_map, NR_ISAIRQS);
-    /* Record of mapped Links */
-    uint8_t link_cnt[NR_LINK];
-    struct timer hvm_timer[NR_IRQS];
-};
 
 struct hvm_irq {
     /*
@@ -149,27 +98,16 @@ struct hvm_irq {
 
 #define hvm_isa_irq_to_gsi(isa_irq) ((isa_irq) ? : 2)
 
-/* Modify state of a PCI INTx wire. */
-void hvm_pci_intx_assert(
-    struct domain *d, unsigned int device, unsigned int intx);
-void hvm_pci_intx_deassert(
-    struct domain *d, unsigned int device, unsigned int intx);
-
-/* Modify state of an ISA device's IRQ wire. */
-void hvm_isa_irq_assert(
-    struct domain *d, unsigned int isa_irq);
-void hvm_isa_irq_deassert(
-    struct domain *d, unsigned int isa_irq);
-
-void hvm_set_pci_link_route(struct domain *d, u8 link, u8 isa_irq);
-
-void hvm_maybe_deassert_evtchn_irq(void);
-void hvm_assert_evtchn_irq(struct vcpu *v);
-void hvm_set_callback_via(struct domain *d, uint64_t via);
-
 /* Check/Acknowledge next pending interrupt. */
 struct hvm_intack hvm_vcpu_has_pending_irq(struct vcpu *v);
 struct hvm_intack hvm_vcpu_ack_pending_irq(struct vcpu *v,
                                            struct hvm_intack intack);
 
+/*
+ * Currently IA64 Xen doesn't support MSI. So for x86, we define this macro
+ * to control the conditional compilation of some MSI-related functions.
+ * This macro will be removed once IA64 has MSI support.
+ */
+#define SUPPORT_MSI_REMAPPING 1
+
 #endif /* __ASM_X86_HVM_IRQ_H__ */
diff -r 6583186e5989 -r 46d7e12c4c91 xen/include/asm-x86/hvm/svm/vmcb.h
--- a/xen/include/asm-x86/hvm/svm/vmcb.h        Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/include/asm-x86/hvm/svm/vmcb.h        Wed Oct 22 11:46:55 2008 +0900
@@ -393,7 +393,9 @@ struct vmcb_struct {
     eventinj_t  eventinj;       /* offset 0xA8 */
     u64 h_cr3;                  /* offset 0xB0 */
     lbrctrl_t lbr_control;      /* offset 0xB8 */
-    u64 res09[104];             /* offset 0xC0 pad to save area */
+    u64 res09;                  /* offset 0xC0 */
+    u64 nextrip;                /* offset 0xC8 */
+    u64 res10a[102];            /* offset 0xD0 pad to save area */
 
     svm_segment_register_t es;      /* offset 1024 */
     svm_segment_register_t cs;
diff -r 6583186e5989 -r 46d7e12c4c91 xen/include/asm-x86/io_apic.h
--- a/xen/include/asm-x86/io_apic.h     Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/include/asm-x86/io_apic.h     Wed Oct 22 11:46:55 2008 +0900
@@ -19,6 +19,8 @@
 #define IO_APIC_BASE(idx) \
                ((volatile int *)(__fix_to_virt(FIX_IO_APIC_BASE_0 + idx) \
                + (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK)))
+
+#define IO_APIC_ID(idx) (mp_ioapics[idx].mpc_apicid)
 
 /*
  * The structure of the IO-APIC:
diff -r 6583186e5989 -r 46d7e12c4c91 xen/include/asm-x86/msi.h
--- a/xen/include/asm-x86/msi.h Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/include/asm-x86/msi.h Wed Oct 22 11:46:55 2008 +0900
@@ -90,10 +90,11 @@ struct msi_desc {
 
        void __iomem *mask_base;
        struct pci_dev *dev;
-    int vector;
-
-       /* Last set MSI message */
-       struct msi_msg msg;
+       int vector;
+
+       struct msi_msg msg;             /* Last set MSI message */
+
+       int remap_index;                /* index in interrupt remapping table */
 };
 
 /*
diff -r 6583186e5989 -r 46d7e12c4c91 xen/include/asm-x86/rwlock.h
--- a/xen/include/asm-x86/rwlock.h      Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/include/asm-x86/rwlock.h      Wed Oct 22 11:46:55 2008 +0900
@@ -22,25 +22,19 @@
 
 #define __build_read_lock_ptr(rw, helper)   \
        asm volatile(LOCK "subl $1,(%0)\n\t" \
-                    "js 2f\n" \
+                    "jns 1f\n\t" \
+                    "call " helper "\n\t" \
                     "1:\n" \
-                    ".section .text.lock,\"ax\"\n" \
-                    "2:\tcall " helper "\n\t" \
-                    "jmp 1b\n" \
-                    ".previous" \
                     ::"a" (rw) : "memory")
 
 #define __build_read_lock_const(rw, helper)   \
        asm volatile(LOCK "subl $1,%0\n\t" \
-                    "js 2f\n" \
-                    "1:\n" \
-                    ".section .text.lock,\"ax\"\n" \
-                    "2:\tpush %%"__OP"ax\n\t" \
+                    "jns 1f\n\t" \
+                    "push %%"__OP"ax\n\t" \
                     "lea %0,%%"__OP"ax\n\t" \
                     "call " helper "\n\t" \
                     "pop %%"__OP"ax\n\t" \
-                    "jmp 1b\n" \
-                    ".previous" \
+                    "1:\n" \
                     :"=m" (*(volatile int *)rw) : : "memory")
 
 #define __build_read_lock(rw, helper)  do { \
@@ -52,25 +46,19 @@
 
 #define __build_write_lock_ptr(rw, helper) \
        asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
-                    "jnz 2f\n" \
+                    "jz 1f\n\t" \
+                    "call " helper "\n\t" \
                     "1:\n" \
-                    ".section .text.lock,\"ax\"\n" \
-                    "2:\tcall " helper "\n\t" \
-                    "jmp 1b\n" \
-                    ".previous" \
                     ::"a" (rw) : "memory")
 
 #define __build_write_lock_const(rw, helper) \
        asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
-                    "jnz 2f\n" \
-                    "1:\n" \
-                    ".section .text.lock,\"ax\"\n" \
-                    "2:\tpush %%"__OP"ax\n\t" \
+                    "jz 1f\n\t" \
+                    "push %%"__OP"ax\n\t" \
                     "lea %0,%%"__OP"ax\n\t" \
                     "call " helper "\n\t" \
                     "pop %%"__OP"ax\n\t" \
-                    "jmp 1b\n" \
-                    ".previous" \
+                    "1:\n" \
                     :"=m" (*(volatile int *)rw) : : "memory")
 
 #define __build_write_lock(rw, helper) do { \
diff -r 6583186e5989 -r 46d7e12c4c91 xen/include/asm-x86/spinlock.h
--- a/xen/include/asm-x86/spinlock.h    Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/include/asm-x86/spinlock.h    Wed Oct 22 11:46:55 2008 +0900
@@ -8,104 +8,71 @@
 
 typedef struct {
     volatile s16 lock;
-    s8 recurse_cpu;
-    u8 recurse_cnt;
-} spinlock_t;
+} raw_spinlock_t;
 
-#define SPIN_LOCK_UNLOCKED /*(spinlock_t)*/ { 1, -1, 0 }
+#define _RAW_SPIN_LOCK_UNLOCKED /*(raw_spinlock_t)*/ { 1 }
 
-#define spin_lock_init(x)      do { *(x) = (spinlock_t) SPIN_LOCK_UNLOCKED; } 
while(0)
-#define spin_is_locked(x)      (*(volatile char *)(&(x)->lock) <= 0)
+#define _raw_spin_is_locked(x)                  \
+    (*(volatile char *)(&(x)->lock) <= 0)
 
-static inline void _raw_spin_lock(spinlock_t *lock)
+static always_inline void _raw_spin_lock(raw_spinlock_t *lock)
 {
-    __asm__ __volatile__ (
-        "1:  lock; decb %0         \n"
-        "    js 2f                 \n"
-        ".section .text.lock,\"ax\"\n"
+    asm volatile (
+        "1:  lock; decw %0         \n"
+        "    jns 3f                \n"
         "2:  rep; nop              \n"
-        "    cmpb $0,%0            \n"
+        "    cmpw $0,%0            \n"
         "    jle 2b                \n"
         "    jmp 1b                \n"
-        ".previous"
+        "3:"
         : "=m" (lock->lock) : : "memory" );
 }
 
-static inline void _raw_spin_unlock(spinlock_t *lock)
+static always_inline void _raw_spin_unlock(raw_spinlock_t *lock)
 {
-    ASSERT(spin_is_locked(lock));
-    __asm__ __volatile__ (
-       "movb $1,%0" 
+    ASSERT(_raw_spin_is_locked(lock));
+    asm volatile (
+        "movw $1,%0" 
         : "=m" (lock->lock) : : "memory" );
 }
 
-static inline int _raw_spin_trylock(spinlock_t *lock)
+static always_inline int _raw_spin_trylock(raw_spinlock_t *lock)
 {
-    char oldval;
-    __asm__ __volatile__(
-        "xchgb %b0,%1"
-        :"=q" (oldval), "=m" (lock->lock)
-        :"0" (0) : "memory");
-    return oldval > 0;
+    s16 oldval;
+    asm volatile (
+        "xchgw %w0,%1"
+        :"=r" (oldval), "=m" (lock->lock)
+        :"0" (0) : "memory" );
+    return (oldval > 0);
 }
-
-/*
- * spin_[un]lock_recursive(): Use these forms when the lock can (safely!) be
- * reentered recursively on the same CPU. All critical regions that may form
- * part of a recursively-nested set must be protected by these forms. If there
- * are any critical regions that cannot form part of such a set, they can use
- * standard spin_[un]lock().
- */
-#define _raw_spin_lock_recursive(_lock)            \
-    do {                                           \
-        int cpu = smp_processor_id();              \
-        if ( likely((_lock)->recurse_cpu != cpu) ) \
-        {                                          \
-            spin_lock(_lock);                      \
-            (_lock)->recurse_cpu = cpu;            \
-        }                                          \
-        (_lock)->recurse_cnt++;                    \
-    } while ( 0 )
-
-#define _raw_spin_unlock_recursive(_lock)          \
-    do {                                           \
-        if ( likely(--(_lock)->recurse_cnt == 0) ) \
-        {                                          \
-            (_lock)->recurse_cpu = -1;             \
-            spin_unlock(_lock);                    \
-        }                                          \
-    } while ( 0 )
-
 
 typedef struct {
     volatile unsigned int lock;
-} rwlock_t;
+} raw_rwlock_t;
 
-#define RW_LOCK_UNLOCKED /*(rwlock_t)*/ { RW_LOCK_BIAS }
-
-#define rwlock_init(x) do { *(x) = (rwlock_t) RW_LOCK_UNLOCKED; } while(0)
+#define _RAW_RW_LOCK_UNLOCKED /*(raw_rwlock_t)*/ { RW_LOCK_BIAS }
 
 /*
  * On x86, we implement read-write locks as a 32-bit counter
  * with the high bit (sign) being the "contended" bit.
  */
-static inline void _raw_read_lock(rwlock_t *rw)
+static always_inline void _raw_read_lock(raw_rwlock_t *rw)
 {
     __build_read_lock(rw, "__read_lock_failed");
 }
 
-static inline void _raw_write_lock(rwlock_t *rw)
+static always_inline void _raw_write_lock(raw_rwlock_t *rw)
 {
     __build_write_lock(rw, "__write_lock_failed");
 }
 
-#define _raw_read_unlock(rw)                       \
-    __asm__ __volatile__ (                         \
-        "lock ; incl %0" :                         \
+#define _raw_read_unlock(rw)                    \
+    asm volatile (                              \
+        "lock ; incl %0" :                      \
         "=m" ((rw)->lock) : : "memory" )
-#define _raw_write_unlock(rw)                      \
-    __asm__ __volatile__ (                         \
-        "lock ; addl $" RW_LOCK_BIAS_STR ",%0" :   \
+#define _raw_write_unlock(rw)                           \
+    asm volatile (                                      \
+        "lock ; addl $" RW_LOCK_BIAS_STR ",%0" :        \
         "=m" ((rw)->lock) : : "memory" )
 
 #endif /* __ASM_SPINLOCK_H */
diff -r 6583186e5989 -r 46d7e12c4c91 xen/include/public/domctl.h
--- a/xen/include/public/domctl.h       Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/include/public/domctl.h       Wed Oct 22 11:46:55 2008 +0900
@@ -614,6 +614,10 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_subsc
 #define XEN_DOMCTL_set_machine_address_size  51
 #define XEN_DOMCTL_get_machine_address_size  52
 
+/*
+ * Do not inject spurious page faults into this domain.
+ */
+#define XEN_DOMCTL_suppress_spurious_page_faults 53
 
 struct xen_domctl {
     uint32_t cmd;
diff -r 6583186e5989 -r 46d7e12c4c91 xen/include/public/trace.h
--- a/xen/include/public/trace.h        Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/include/public/trace.h        Wed Oct 22 11:46:55 2008 +0900
@@ -38,6 +38,7 @@
 #define TRC_MEM      0x0010f000    /* Xen memory trace         */
 #define TRC_PV       0x0020f000    /* Xen PV traces            */
 #define TRC_SHADOW   0x0040f000    /* Xen shadow tracing       */
+#define TRC_PM       0x0080f000    /* Xen power management trace */
 #define TRC_ALL      0x0ffff000
 #define TRC_HD_TO_EVENT(x) ((x)&0x0fffffff)
 #define TRC_HD_CYCLE_FLAG (1UL<<31)
@@ -146,6 +147,15 @@
 #define TRC_HVM_LMSW            (TRC_HVM_HANDLER + 0x19)
 #define TRC_HVM_LMSW64          (TRC_HVM_HANDLER + TRC_64_FLAG + 0x19)
 
+/* trace subclasses for power management */
+#define TRC_PM_FREQ     0x00801000      /* xen cpu freq events */
+#define TRC_PM_IDLE     0x00802000      /* xen cpu idle events */
+
+/* trace events for per class */
+#define TRC_PM_FREQ_CHANGE      (TRC_PM_FREQ + 0x01)
+#define TRC_PM_IDLE_ENTRY       (TRC_PM_IDLE + 0x01)
+#define TRC_PM_IDLE_EXIT        (TRC_PM_IDLE + 0x02)
+
 /* This structure represents a single trace buffer record. */
 struct t_rec {
     uint32_t event:28;
diff -r 6583186e5989 -r 46d7e12c4c91 xen/include/xen/hvm/irq.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/xen/hvm/irq.h Wed Oct 22 11:46:55 2008 +0900
@@ -0,0 +1,99 @@
+/******************************************************************************
+ * irq.h
+ * 
+ * Interrupt distribution and delivery logic.
+ * 
+ * Copyright (c) 2006, K A Fraser, XenSource Inc.
+ *
+ * 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.
+ */
+
+#ifndef __XEN_HVM_IRQ_H__
+#define __XEN_HVM_IRQ_H__
+
+#include <xen/types.h>
+#include <xen/spinlock.h>
+#include <asm/irq.h>
+#include <public/hvm/save.h>
+
+struct dev_intx_gsi_link {
+    struct list_head list;
+    uint8_t device;
+    uint8_t intx;
+    uint8_t gsi;
+    uint8_t link;
+};
+
+#define _HVM_IRQ_DPCI_MSI  0x1
+
+struct hvm_gmsi_info {
+    uint32_t gvec;
+    uint32_t gflags;
+};
+
+struct hvm_mirq_dpci_mapping {
+    uint32_t flags;
+    int pending;
+    struct list_head digl_list;
+    struct domain *dom;
+    struct hvm_gmsi_info gmsi;
+};
+
+struct hvm_girq_dpci_mapping {
+    uint8_t valid;
+    uint8_t device;
+    uint8_t intx;
+    uint8_t machine_gsi;
+};
+
+#define NR_ISAIRQS  16
+#define NR_LINK     4
+
+/* Protected by domain's event_lock */
+struct hvm_irq_dpci {
+    /* Machine IRQ to guest device/intx mapping. */
+    DECLARE_BITMAP(mapping, NR_PIRQS);
+    struct hvm_mirq_dpci_mapping mirq[NR_IRQS];
+    /* Guest IRQ to guest device/intx mapping. */
+    struct hvm_girq_dpci_mapping girq[NR_IRQS];
+    uint8_t msi_gvec_pirq[NR_VECTORS];
+    DECLARE_BITMAP(dirq_mask, NR_IRQS);
+    /* Record of mapped ISA IRQs */
+    DECLARE_BITMAP(isairq_map, NR_ISAIRQS);
+    /* Record of mapped Links */
+    uint8_t link_cnt[NR_LINK];
+    struct timer hvm_timer[NR_IRQS];
+};
+
+/* Modify state of a PCI INTx wire. */
+void hvm_pci_intx_assert(
+    struct domain *d, unsigned int device, unsigned int intx);
+void hvm_pci_intx_deassert(
+    struct domain *d, unsigned int device, unsigned int intx);
+
+/* Modify state of an ISA device's IRQ wire. */
+void hvm_isa_irq_assert(
+    struct domain *d, unsigned int isa_irq);
+void hvm_isa_irq_deassert(
+    struct domain *d, unsigned int isa_irq);
+
+void hvm_set_pci_link_route(struct domain *d, u8 link, u8 isa_irq);
+
+void hvm_maybe_deassert_evtchn_irq(void);
+void hvm_assert_evtchn_irq(struct vcpu *v);
+void hvm_set_callback_via(struct domain *d, uint64_t via);
+
+void hvm_dirq_assist(struct vcpu *v);
+
+#endif /* __XEN_HVM_IRQ_H__ */
diff -r 6583186e5989 -r 46d7e12c4c91 xen/include/xen/spinlock.h
--- a/xen/include/xen/spinlock.h        Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/include/xen/spinlock.h        Wed Oct 22 11:46:55 2008 +0900
@@ -3,93 +3,95 @@
 
 #include <xen/config.h>
 #include <asm/system.h>
-
-#define spin_lock_irqsave(lock, flags) \
-    do { local_irq_save(flags); spin_lock(lock); } while ( 0 )
-#define spin_lock_irq(lock) \
-    do { local_irq_disable(); spin_lock(lock); } while ( 0 )
-
-#define read_lock_irqsave(lock, flags) \
-    do { local_irq_save(flags); read_lock(lock); } while ( 0 )
-#define read_lock_irq(lock) \
-    do { local_irq_disable(); read_lock(lock); } while ( 0 )
-
-#define write_lock_irqsave(lock, flags) \
-    do { local_irq_save(flags); write_lock(lock); } while ( 0 )
-#define write_lock_irq(lock) \
-    do { local_irq_disable(); write_lock(lock); } while ( 0 )
-
-#define spin_unlock_irqrestore(lock, flags) \
-    do { spin_unlock(lock); local_irq_restore(flags); } while ( 0 )
-#define spin_unlock_irq(lock) \
-    do { spin_unlock(lock); local_irq_enable(); } while ( 0 )
-
-#define read_unlock_irqrestore(lock, flags) \
-    do { read_unlock(lock); local_irq_restore(flags); } while ( 0 )
-#define read_unlock_irq(lock) \
-    do { read_unlock(lock); local_irq_enable(); } while ( 0 )
-
-#define write_unlock_irqrestore(lock, flags) \
-    do { write_unlock(lock); local_irq_restore(flags); } while ( 0 )
-#define write_unlock_irq(lock) \
-    do { write_unlock(lock); local_irq_enable(); } while ( 0 )
-
-#ifdef CONFIG_SMP
-
 #include <asm/spinlock.h>
 
-#else
+typedef struct {
+    raw_spinlock_t raw;
+    u16 recurse_cpu:12;
+    u16 recurse_cnt:4;
+} spinlock_t;
 
-#if (__GNUC__ > 2)
-typedef struct { } spinlock_t;
-#define SPIN_LOCK_UNLOCKED /*(spinlock_t)*/ { }
-#else
-typedef struct { int gcc_is_buggy; } spinlock_t;
-#define SPIN_LOCK_UNLOCKED /*(spinlock_t)*/ { 0 }
-#endif
+#define SPIN_LOCK_UNLOCKED { _RAW_SPIN_LOCK_UNLOCKED, 0xfffu, 0 }
+#define DEFINE_SPINLOCK(l) spinlock_t l = SPIN_LOCK_UNLOCKED
+#define spin_lock_init(l) (*(l) = (spinlock_t)SPIN_LOCK_UNLOCKED)
 
-#define spin_lock_init(lock)             do { } while(0)
-#define spin_is_locked(lock)             (0)
-#define _raw_spin_lock(lock)             (void)(lock)
-#define _raw_spin_trylock(lock)          ({1; })
-#define _raw_spin_unlock(lock)           do { } while(0)
-#define _raw_spin_lock_recursive(lock)   do { } while(0)
-#define _raw_spin_unlock_recursive(lock) do { } while(0)
+typedef struct {
+    raw_rwlock_t raw;
+} rwlock_t;
 
-#if (__GNUC__ > 2)
-typedef struct { } rwlock_t;
-#define RW_LOCK_UNLOCKED /*(rwlock_t)*/ { }
-#else
-typedef struct { int gcc_is_buggy; } rwlock_t;
-#define RW_LOCK_UNLOCKED /*(rwlock_t)*/ { 0 }
-#endif
+#define RW_LOCK_UNLOCKED { _RAW_RW_LOCK_UNLOCKED }
+#define DEFINE_RWLOCK(l) rwlock_t l = RW_LOCK_UNLOCKED
+#define rwlock_init(l) (*(l) = (rwlock_t)RW_LOCK_UNLOCKED)
 
-#define rwlock_init(lock)            do { } while(0)
-#define _raw_read_lock(lock)         (void)(lock) /* Not "unused variable". */
-#define _raw_read_unlock(lock)       do { } while(0)
-#define _raw_write_lock(lock)        (void)(lock) /* Not "unused variable". */
-#define _raw_write_unlock(lock)      do { } while(0)
+void _spin_lock(spinlock_t *lock);
+void _spin_lock_irq(spinlock_t *lock);
+unsigned long _spin_lock_irqsave(spinlock_t *lock);
 
-#endif
+void _spin_unlock(spinlock_t *lock);
+void _spin_unlock_irq(spinlock_t *lock);
+void _spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags);
 
-#define spin_lock(_lock)             _raw_spin_lock(_lock)
-#define spin_trylock(_lock)          _raw_spin_trylock(_lock)
-#define spin_unlock(_lock)           _raw_spin_unlock(_lock)
-#define spin_lock_recursive(_lock)   _raw_spin_lock_recursive(_lock)
-#define spin_unlock_recursive(_lock) _raw_spin_unlock_recursive(_lock)
-#define read_lock(_lock)             _raw_read_lock(_lock)
-#define read_unlock(_lock)           _raw_read_unlock(_lock)
-#define write_lock(_lock)            _raw_write_lock(_lock)
-#define write_unlock(_lock)          _raw_write_unlock(_lock)
+int _spin_is_locked(spinlock_t *lock);
+int _spin_trylock(spinlock_t *lock);
+void _spin_barrier(spinlock_t *lock);
+
+void _spin_lock_recursive(spinlock_t *lock);
+void _spin_unlock_recursive(spinlock_t *lock);
+
+void _read_lock(rwlock_t *lock);
+void _read_lock_irq(rwlock_t *lock);
+unsigned long _read_lock_irqsave(rwlock_t *lock);
+
+void _read_unlock(rwlock_t *lock);
+void _read_unlock_irq(rwlock_t *lock);
+void _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags);
+
+void _write_lock(rwlock_t *lock);
+void _write_lock_irq(rwlock_t *lock);
+unsigned long _write_lock_irqsave(rwlock_t *lock);
+
+void _write_unlock(rwlock_t *lock);
+void _write_unlock_irq(rwlock_t *lock);
+void _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags);
+
+#define spin_lock(l)                  _spin_lock(l)
+#define spin_lock_irq(l)              _spin_lock_irq(l)
+#define spin_lock_irqsave(l, f)       ((f) = _spin_lock_irqsave(l))
+
+#define spin_unlock(l)                _spin_unlock(l)
+#define spin_unlock_irq(l)            _spin_unlock_irq(l)
+#define spin_unlock_irqrestore(l, f)  _spin_unlock_irqrestore(l, f)
+
+#define spin_is_locked(l)             _raw_spin_is_locked(&(l)->raw)
+#define spin_trylock(l)               _spin_trylock(l)
 
 /* Ensure a lock is quiescent between two critical operations. */
-static inline void spin_barrier(spinlock_t *lock)
-{
-    do { mb(); } while ( spin_is_locked(lock) );
-    mb();
-}
+#define spin_barrier(l)               _spin_barrier(l)
 
-#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED
-#define DEFINE_RWLOCK(x) rwlock_t x = RW_LOCK_UNLOCKED
+/*
+ * spin_[un]lock_recursive(): Use these forms when the lock can (safely!) be
+ * reentered recursively on the same CPU. All critical regions that may form
+ * part of a recursively-nested set must be protected by these forms. If there
+ * are any critical regions that cannot form part of such a set, they can use
+ * standard spin_[un]lock().
+ */
+#define spin_lock_recursive(l)        _spin_lock_recursive(l)
+#define spin_unlock_recursive(l)      _spin_unlock_recursive(l)
+
+#define read_lock(l)                  _read_lock(l)
+#define read_lock_irq(l)              _read_lock_irq(l)
+#define read_lock_irqsave(l, f)       ((f) = _read_lock_irqsave(l))
+
+#define read_unlock(l)                _read_unlock(l)
+#define read_unlock_irq(l)            _read_unlock_irq(l)
+#define read_unlock_irqrestore(l, f)  _read_unlock_irqrestore(l, f)
+
+#define write_lock(l)                 _write_lock(l)
+#define write_lock_irq(l)             _write_lock_irq(l)
+#define write_lock_irqsave(l, f)      ((f) = _write_lock_irqsave(l))
+
+#define write_unlock(l)               _write_unlock(l)
+#define write_unlock_irq(l)           _write_unlock_irq(l)
+#define write_unlock_irqrestore(l, f) _write_unlock_irqrestore(l, f)
 
 #endif /* __SPINLOCK_H__ */
diff -r 6583186e5989 -r 46d7e12c4c91 xen/include/xen/xmalloc.h
--- a/xen/include/xen/xmalloc.h Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/include/xen/xmalloc.h Wed Oct 22 11:46:55 2008 +0900
@@ -1,12 +1,17 @@
 
 #ifndef __XMALLOC_H__
 #define __XMALLOC_H__
+
+/*
+ * Xen malloc/free-style interface.
+ */
 
 /* Allocate space for typed object. */
 #define xmalloc(_type) ((_type *)_xmalloc(sizeof(_type), __alignof__(_type)))
 
 /* Allocate space for array of typed objects. */
-#define xmalloc_array(_type, _num) ((_type *)_xmalloc_array(sizeof(_type), 
__alignof__(_type), _num))
+#define xmalloc_array(_type, _num) \
+    ((_type *)_xmalloc_array(sizeof(_type), __alignof__(_type), _num))
 
 /* Allocate untyped storage. */
 #define xmalloc_bytes(_bytes) (_xmalloc(_bytes, SMP_CACHE_BYTES))
@@ -15,8 +20,9 @@ extern void xfree(void *);
 extern void xfree(void *);
 
 /* Underlying functions */
-extern void *_xmalloc(size_t size, size_t align);
-static inline void *_xmalloc_array(size_t size, size_t align, size_t num)
+extern void *_xmalloc(unsigned long size, unsigned long align);
+static inline void *_xmalloc_array(
+    unsigned long size, unsigned long align, unsigned long num)
 {
        /* Check for overflow. */
        if (size && num > UINT_MAX / size)
@@ -24,4 +30,73 @@ static inline void *_xmalloc_array(size_
        return _xmalloc(size * num, align);
 }
 
+/*
+ * Pooled allocator interface.
+ */
+
+struct xmem_pool;
+
+typedef void *(xmem_pool_get_memory)(unsigned long bytes);
+typedef void (xmem_pool_put_memory)(void *ptr);
+
+/**
+ * xmem_pool_create - create dynamic memory pool
+ * @name: name of the pool
+ * @get_mem: callback function used to expand pool
+ * @put_mem: callback function used to shrink pool
+ * @init_size: inital pool size (in bytes)
+ * @max_size: maximum pool size (in bytes) - set this as 0 for no limit
+ * @grow_size: amount of memory (in bytes) added to pool whenever required
+ *
+ * All size values are rounded up to next page boundary.
+ */
+struct xmem_pool *xmem_pool_create(
+    const char *name,
+    xmem_pool_get_memory get_mem,
+    xmem_pool_put_memory put_mem,
+    unsigned long init_size,
+    unsigned long max_size,
+    unsigned long grow_size);
+
+/**
+ * xmem_pool_destroy - cleanup given pool
+ * @mem_pool: Pool to be destroyed
+ *
+ * Data structures associated with pool are freed.
+ * All memory allocated from pool must be freed before
+ * destorying it.
+ */
+void xmem_pool_destroy(struct xmem_pool *pool);
+
+/**
+ * xmem_pool_alloc - allocate memory from given pool
+ * @size: no. of bytes
+ * @mem_pool: pool to allocate from
+ */
+void *xmem_pool_alloc(unsigned long size, struct xmem_pool *pool);
+
+/**
+ * xmem_pool_free - free memory from given pool
+ * @ptr: address of memory to be freed
+ * @mem_pool: pool to free from
+ */
+void xmem_pool_free(void *ptr, struct xmem_pool *pool);
+
+/**
+ * xmem_pool_get_used_size - get memory currently used by given pool
+ *
+ * Used memory includes stored data + metadata + internal fragmentation
+ */
+unsigned long xmem_pool_get_used_size(struct xmem_pool *pool);
+
+/**
+ * xmem_pool_get_total_size - get total memory currently allocated for pool
+ *
+ * This is the total memory currently allocated for this pool which includes
+ * used size + free size.
+ *
+ * (Total - Used) is good indicator of memory efficiency of allocator.
+ */
+unsigned long xmem_pool_get_total_size(struct xmem_pool *pool);
+
 #endif /* __XMALLOC_H__ */
diff -r 6583186e5989 -r 46d7e12c4c91 xen/include/xlat.lst
--- a/xen/include/xlat.lst      Wed Oct 22 11:38:22 2008 +0900
+++ b/xen/include/xlat.lst      Wed Oct 22 11:46:55 2008 +0900
@@ -55,3 +55,7 @@
 !      processor_cx                    platform.h
 !      processor_flags                 platform.h
 !      processor_power                 platform.h
+!      pct_register                    platform.h
+!      processor_px                    platform.h
+!      psd_package                     platform.h
+!      processor_performance           platform.h

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>