ia64/xen-unstable

changeset 18282:a39913db6e51

merge with xen-unstable.hg
author Isaku Yamahata <yamahata@valinux.co.jp>
date Thu Aug 07 11:57:34 2008 +0900 (2008-08-07)
parents 7affdebb7a1e eff5fcfa69bc
children 36c274bbc5df
files tools/examples/stubdom-ExampleHVMDomain xen/arch/ia64/xen/irq.c
line diff
     1.1 --- a/.hgignore	Thu Aug 07 11:47:34 2008 +0900
     1.2 +++ b/.hgignore	Thu Aug 07 11:57:34 2008 +0900
     1.3 @@ -21,8 +21,7 @@
     1.4  ^[^/]*\.bz2$
     1.5  ^\.config$
     1.6  ^\.pc
     1.7 -^TAGS$
     1.8 -^tags$
     1.9 +(^|/)(tags|TAGS)$
    1.10  ^build-.*$
    1.11  ^dist/.*$
    1.12  ^docs/.*\.aux$
    1.13 @@ -60,10 +59,13 @@
    1.14  ^docs/xen-api/vm_lifecycle.eps$
    1.15  ^docs/xen-api/xenapi-datamodel-graph.eps$
    1.16  ^docs/xen-api/xenapi.out$
    1.17 -^extras/mini-os/h/hypervisor-ifs$
    1.18 -^extras/mini-os/h/xen-public$
    1.19 +^extras/mini-os/arch/ia64/gen_off.s$
    1.20 +^extras/mini-os/include/mini-os$
    1.21 +^extras/mini-os/include/ia64/mini-os$
    1.22 +^extras/mini-os/include/ia64/offsets.h$
    1.23 +^extras/mini-os/include/x86/mini-os$
    1.24 +^extras/mini-os/include/xen$
    1.25  ^extras/mini-os/mini-os.*$
    1.26 -^extras/mini-os/*-stubdom.*$
    1.27  ^install/.*$
    1.28  ^linux-[^/]*-paravirt/.*$
    1.29  ^linux-2.6[^/]*/.*$
    1.30 @@ -91,13 +93,17 @@
    1.31  ^stubdom/libxc$
    1.32  ^stubdom/lwip-.*$
    1.33  ^stubdom/mini-os-.*$
    1.34 +^stubdom/mk-headers$
    1.35  ^stubdom/newlib-.*$
    1.36  ^stubdom/pciutils-.*$
    1.37  ^stubdom/zlib-.*$
    1.38  ^stubdom/grub-cvs$
    1.39  ^stubdom/grub/stage2$
    1.40  ^stubdom/grub/netboot$
    1.41 -^tools/.*/TAGS$
    1.42 +^stubdom/grub/dirs$
    1.43 +^stubdom/lwip/
    1.44 +^stubdom/ioemu/
    1.45 +^stubdom/grub-upstream/
    1.46  ^tools/.*/build/lib.*/.*\.py$
    1.47  ^tools/blktap/Makefile\.smh$
    1.48  ^tools/blktap/drivers/blktapctrl$
    1.49 @@ -253,7 +259,6 @@
    1.50  ^xen/\.banner.*$
    1.51  ^xen/BLOG$
    1.52  ^xen/System.map$
    1.53 -^xen/TAGS$
    1.54  ^xen/arch/x86/asm-offsets\.s$
    1.55  ^xen/arch/x86/boot/mkelf32$
    1.56  ^xen/arch/x86/xen\.lds$
    1.57 @@ -271,7 +276,6 @@
    1.58  ^xen/include/xen/acm_policy\.h$
    1.59  ^xen/include/xen/banner\.h$
    1.60  ^xen/include/xen/compile\.h$
    1.61 -^xen/tags$
    1.62  ^xen/tools/figlet/figlet$
    1.63  ^xen/tools/symbols$
    1.64  ^xen/xen$
     2.1 --- a/.hgtags	Thu Aug 07 11:47:34 2008 +0900
     2.2 +++ b/.hgtags	Thu Aug 07 11:57:34 2008 +0900
     2.3 @@ -25,3 +25,5 @@ ed79613b48817d5e0d1f9b3cf104c0e4e8b0d8cf
     2.4  c5deb251b9dcece9e466a48a66d3528ca1797db4 3.2.0-rc4
     2.5  36bb2ab4722733d919d32e4555eb46cc6a06cb8f 3.2.0-rc5
     2.6  9facc624a238f2b9437b07fa28ff65884aa867f2 3.2.0-rc6
     2.7 +c3494402098e26507fc61a6579832c0149351d6a 3.3.0-rc1
     2.8 +dde12ff94c96331668fe38a7b09506fa94d03c34 3.3.0-rc2
     3.1 --- a/Config.mk	Thu Aug 07 11:47:34 2008 +0900
     3.2 +++ b/Config.mk	Thu Aug 07 11:57:34 2008 +0900
     3.3 @@ -19,6 +19,8 @@ HOSTCFLAGS += -fno-strict-aliasing
     3.4  
     3.5  DISTDIR     ?= $(XEN_ROOT)/dist
     3.6  DESTDIR     ?= /
     3.7 +DOCDIR      ?= /usr/share/doc/xen
     3.8 +MANDIR      ?= /usr/share/man
     3.9  
    3.10  # Allow phony attribute to be listed as dependency rather than fake target
    3.11  .PHONY: .phony
    3.12 @@ -84,7 +86,11 @@ QEMU_REMOTE=http://xenbits.xensource.com
    3.13  # Mercurial in-tree version, or a local directory, or a git URL.
    3.14  # CONFIG_QEMU   ?= ioemu
    3.15  # CONFIG_QEMU   ?= ../qemu-xen.git
    3.16 +ifeq ($(XEN_TARGET_ARCH),ia64)
    3.17 +CONFIG_QEMU   ?= ioemu
    3.18 +else
    3.19  CONFIG_QEMU   ?= $(QEMU_REMOTE)
    3.20 +endif
    3.21  
    3.22  # Optional components
    3.23  XENSTAT_XENTOP     ?= y
     4.1 --- a/Makefile	Thu Aug 07 11:47:34 2008 +0900
     4.2 +++ b/Makefile	Thu Aug 07 11:57:34 2008 +0900
     4.3 @@ -149,7 +149,7 @@ help:
     4.4  	@echo '                     trees then make dist'
     4.5  	@echo '  xen              - build and install Xen hypervisor'
     4.6  	@echo '  tools            - build and install tools'
     4.7 -	@echo '  stubdomain       - build and install the stubdomain images'
     4.8 +	@echo '  stubdom          - build and install the stubdomain images'
     4.9  	@echo '  kernels          - build and install guest kernels'
    4.10  	@echo '  kbuild           - synonym for make kernels'
    4.11  	@echo '  docs             - build and install user documentation'
     5.1 --- a/README	Thu Aug 07 11:47:34 2008 +0900
     5.2 +++ b/README	Thu Aug 07 11:57:34 2008 +0900
     5.3 @@ -1,10 +1,10 @@
     5.4  #################################
     5.5 - __  __            _____  _____  
     5.6 - \ \/ /___ _ __   |___ / |___ /  
     5.7 -  \  // _ \ '_ \    |_ \   |_ \  
     5.8 -  /  \  __/ | | |  ___) | ___) | 
     5.9 - /_/\_\___|_| |_| |____(_)____/  
    5.10 -                                 
    5.11 + __  __            _  _    ___  
    5.12 + \ \/ /___ _ __   | || |  / _ \ 
    5.13 +  \  // _ \ '_ \  | || |_| | | |
    5.14 +  /  \  __/ | | | |__   _| |_| |
    5.15 + /_/\_\___|_| |_|    |_|(_)___/ 
    5.16 +                                
    5.17  #################################
    5.18  
    5.19  http://www.xen.org/
    5.20 @@ -21,7 +21,7 @@ development community, spearheaded by Xe
    5.21  by the original Xen development team to build enterprise products
    5.22  around Xen.
    5.23  
    5.24 -The 3.3 release offers excellent performance, hardware support and
    5.25 +The 4.0 release offers excellent performance, hardware support and
    5.26  enterprise-grade features such as x86_32-PAE, x86_64, SMP guests and
    5.27  live relocation of VMs. Ports to Linux 2.6, Linux 2.4, NetBSD, FreeBSD
    5.28  and Solaris are available from the community.
    5.29 @@ -54,8 +54,8 @@ 2. Configure your bootloader to boot Xen
    5.30     /boot/grub/menu.lst: edit this file to include an entry like the
    5.31     following:
    5.32  
    5.33 -    title Xen 3.3 / XenLinux 2.6
    5.34 -       kernel /boot/xen-3.3.gz console=vga
    5.35 +    title Xen 4.0 / XenLinux 2.6
    5.36 +       kernel /boot/xen-4.0.gz console=vga
    5.37         module /boot/vmlinuz-2.6-xen root=<root-dev> ro console=tty0
    5.38         module /boot/initrd-2.6-xen.img
    5.39  
    5.40 @@ -74,7 +74,7 @@ 2. Configure your bootloader to boot Xen
    5.41     32MB memory for internal use, which is not available for allocation
    5.42     to virtual machines.
    5.43  
    5.44 -3. Reboot your system and select the "Xen 3.3 / XenLinux 2.6" menu
    5.45 +3. Reboot your system and select the "Xen 4.0 / XenLinux 2.6" menu
    5.46     option. After booting Xen, Linux will start and your initialisation
    5.47     scripts should execute in the usual way.
    5.48  
    5.49 @@ -224,6 +224,6 @@ tarballs of the source.  Instructions in
    5.50  to modify grub.conf to use tboot to launch Xen.
    5.51  
    5.52  There are optional targets as part of Xen's top-level makefile that will
    5.53 -downlaod and build tboot: install-tboot, build-tboot, dist-tboot, clean-tboot.
    5.54 +download and build tboot: install-tboot, build-tboot, dist-tboot, clean-tboot.
    5.55  These will download the latest tar file from the SourceForge site using wget,
    5.56  then build/install/dist according to Xen's settings.
     6.1 --- a/docs/Docs.mk	Thu Aug 07 11:47:34 2008 +0900
     6.2 +++ b/docs/Docs.mk	Thu Aug 07 11:57:34 2008 +0900
     6.3 @@ -7,7 +7,3 @@ DOXYGEN		:= doxygen
     6.4  POD2MAN		:= pod2man
     6.5  DOT		:= dot
     6.6  NEATO		:= neato
     6.7 -
     6.8 -pkgdocdir	:= /usr/share/doc/xen
     6.9 -mandir		:= /usr/share/man
    6.10 -
     7.1 --- a/docs/Makefile	Thu Aug 07 11:47:34 2008 +0900
     7.2 +++ b/docs/Makefile	Thu Aug 07 11:57:34 2008 +0900
     7.3 @@ -80,17 +80,17 @@ distclean: clean
     7.4  
     7.5  .PHONY: install
     7.6  install: all
     7.7 -	rm -rf $(DESTDIR)$(pkgdocdir)
     7.8 -	$(INSTALL_DIR) $(DESTDIR)$(pkgdocdir)
     7.9 +	rm -rf $(DESTDIR)$(DOCDIR)
    7.10 +	$(INSTALL_DIR) $(DESTDIR)$(DOCDIR)
    7.11  
    7.12  	$(MAKE) -C xen-api install
    7.13  
    7.14 -	cp -dR ps $(DESTDIR)$(pkgdocdir)
    7.15 -	cp -dR pdf $(DESTDIR)$(pkgdocdir)
    7.16 -	$(INSTALL_DIR) $(DESTDIR)$(mandir)
    7.17 -	cp -dR man1 $(DESTDIR)$(mandir)
    7.18 -	cp -dR man5 $(DESTDIR)$(mandir)
    7.19 -	[ ! -d html ] || cp -dR html $(DESTDIR)$(pkgdocdir)
    7.20 +	cp -dR ps $(DESTDIR)$(DOCDIR)
    7.21 +	cp -dR pdf $(DESTDIR)$(DOCDIR)
    7.22 +	$(INSTALL_DIR) $(DESTDIR)$(MANDIR)
    7.23 +	cp -dR man1 $(DESTDIR)$(MANDIR)
    7.24 +	cp -dR man5 $(DESTDIR)$(MANDIR)
    7.25 +	[ ! -d html ] || cp -dR html $(DESTDIR)$(DOCDIR)
    7.26  
    7.27  pdf/%.pdf: ps/%.ps
    7.28  	$(INSTALL_DIR) $(@D)
     8.1 --- a/docs/misc/vtd.txt	Thu Aug 07 11:47:34 2008 +0900
     8.2 +++ b/docs/misc/vtd.txt	Thu Aug 07 11:57:34 2008 +0900
     8.3 @@ -2,7 +2,7 @@ Title   : How to do PCI Passthrough with
     8.4  Authors : Allen Kay    <allen.m.kay@intel.com>
     8.5            Weidong Han  <weidong.han@intel.com>
     8.6  Created : October-24-2007
     8.7 -Updated : May-07-2008
     8.8 +Updated : August-06-2008
     8.9  
    8.10  How to turn on VT-d in Xen
    8.11  --------------------------
    8.12 @@ -21,7 +21,7 @@ 11) "hide" pci device from dom0 as follo
    8.13  
    8.14  title Xen-Fedora Core (2.6.18-xen)
    8.15          root (hd0,0)
    8.16 -        kernel /boot/xen.gz com1=115200,8n1 console=com1
    8.17 +        kernel /boot/xen.gz com1=115200,8n1 console=com1 iommu=1
    8.18          module /boot/vmlinuz-2.6.18.8-xen root=LABEL=/ ro xencons=ttyS console=tty0 console=ttyS0, pciback.hide=(01:00.0)(03:00.0)
    8.19          module /boot/initrd-2.6.18-xen.img
    8.20  
    8.21 @@ -32,6 +32,11 @@ 15) start hvm guest and use "lspci" to s
    8.22      "ifconfig" to see if IP address has been assigned to NIC devices.
    8.23  
    8.24  
    8.25 +Enable MSI/MSI-x for assigned devices
    8.26 +-------------------------------------
    8.27 +Add "msi=1" option in kernel line of host grub.
    8.28 +
    8.29 +
    8.30  Caveat on Conventional PCI Device Passthrough
    8.31  ---------------------------------------------
    8.32  
     9.1 --- a/docs/src/user.tex	Thu Aug 07 11:47:34 2008 +0900
     9.2 +++ b/docs/src/user.tex	Thu Aug 07 11:57:34 2008 +0900
     9.3 @@ -4204,11 +4204,9 @@ writing to the VGA console after domain 
     9.4    enabled by the BIOS.
     9.5  \item [ apic=bigsmp,default,es7000,summit ] Specify NUMA platform.
     9.6    This can usually be probed automatically.
     9.7 -\item [ dma\_bits=xxx ] Specify width of DMA
     9.8 -  addresses in bits. Default is 30 bits (addresses up to 1GB are DMAable).
     9.9 -\item [ dma\_emergency\_pool=xxx ] Specify lower bound on size of DMA
    9.10 -  pool below which ordinary allocations will fail rather than fall
    9.11 -  back to allocating from the DMA pool.
    9.12 +\item [ dma\_bits=xxx ] Specify width of DMA addresses in bits. This
    9.13 +  is used in NUMA systems to prevent this special DMA memory from
    9.14 +  being exhausted in one node when remote nodes have available memory.
    9.15  \end{description}
    9.16  
    9.17  In addition, the following options may be specified on the Xen command
    10.1 --- a/docs/xen-api/Makefile	Thu Aug 07 11:47:34 2008 +0900
    10.2 +++ b/docs/xen-api/Makefile	Thu Aug 07 11:57:34 2008 +0900
    10.3 @@ -16,11 +16,11 @@ all: build
    10.4  build: xenapi.pdf xenapi.ps
    10.5  
    10.6  install:
    10.7 -	$(INSTALL_DIR) $(DESTDIR)$(pkgdocdir)/ps
    10.8 -	$(INSTALL_DIR) $(DESTDIR)$(pkgdocdir)/pdf
    10.9 +	$(INSTALL_DIR) $(DESTDIR)$(DOCDIR)/ps
   10.10 +	$(INSTALL_DIR) $(DESTDIR)$(DOCDIR)/pdf
   10.11  
   10.12 -	[ -e xenapi.ps ] && cp xenapi.ps $(DESTDIR)$(pkgdocdir)/ps || true
   10.13 -	[ -e xenapi.pdf ] && cp xenapi.pdf $(DESTDIR)$(pkgdocdir)/pdf || true
   10.14 +	[ -e xenapi.ps ] && cp xenapi.ps $(DESTDIR)$(DOCDIR)/ps || true
   10.15 +	[ -e xenapi.pdf ] && cp xenapi.pdf $(DESTDIR)$(DOCDIR)/pdf || true
   10.16  
   10.17  xenapi.dvi: $(TEX) $(EPS) $(EPSDOT)
   10.18  	$(LATEX) xenapi.tex
    11.1 --- a/docs/xen-api/coversheet.tex	Thu Aug 07 11:47:34 2008 +0900
    11.2 +++ b/docs/xen-api/coversheet.tex	Thu Aug 07 11:57:34 2008 +0900
    11.3 @@ -50,7 +50,7 @@ Gareth Bestor, IBM & Jon Ludlam, XenSour
    11.4  Hollis Blanchard, IBM & Alastair Tse, XenSource \\
    11.5  Mike Day, IBM & Daniel Veillard, Red Hat \\
    11.6  Jim Fehlig, Novell & Tom Wilkie, University of Cambridge \\
    11.7 -Jon Harrop, XenSource & \\
    11.8 +Jon Harrop, XenSource & Yosuke Iwamatsu, NEC \\
    11.9  \end{tabular}
   11.10  \end{large}
   11.11  
   11.12 @@ -60,4 +60,4 @@ Jon Harrop, XenSource & \\
   11.13  \legalnotice{}
   11.14  
   11.15  \newpage
   11.16 -\pagestyle{fancy}
   11.17 \ No newline at end of file
   11.18 +\pagestyle{fancy}
    12.1 --- a/docs/xen-api/revision-history.tex	Thu Aug 07 11:47:34 2008 +0900
    12.2 +++ b/docs/xen-api/revision-history.tex	Thu Aug 07 11:57:34 2008 +0900
    12.3 @@ -47,5 +47,14 @@
    12.4      \end{flushleft}
    12.5     \end{minipage}\\
    12.6    \hline
    12.7 +  1.0.6 & 24th Jul. 08 & Y. Iwamatsu &
    12.8 +   \begin{minipage}[t]{7cm}
    12.9 +    \begin{flushleft}
   12.10 +     Added definitions of new classes DPCI and PPCI. Updated the table
   12.11 +     and the diagram representing relationships between classes.
   12.12 +     Added host.PPCIs and VM.DPCIs fields.
   12.13 +    \end{flushleft}
   12.14 +   \end{minipage}\\
   12.15 +  \hline
   12.16   \end{tabular}
   12.17  \end{center}
    13.1 --- a/docs/xen-api/xenapi-coversheet.tex	Thu Aug 07 11:47:34 2008 +0900
    13.2 +++ b/docs/xen-api/xenapi-coversheet.tex	Thu Aug 07 11:57:34 2008 +0900
    13.3 @@ -17,12 +17,12 @@
    13.4  \newcommand{\coversheetlogo}{xen.eps}
    13.5  
    13.6  %% Document date
    13.7 -\newcommand{\datestring}{11th February 2008}
    13.8 +\newcommand{\datestring}{24th July 2008}
    13.9  
   13.10  \newcommand{\releasestatement}{Stable Release}
   13.11  
   13.12  %% Document revision
   13.13 -\newcommand{\revstring}{API Revision 1.0.5}
   13.14 +\newcommand{\revstring}{API Revision 1.0.6}
   13.15  
   13.16  %% Document authors
   13.17  \newcommand{\docauthors}{
    14.1 --- a/docs/xen-api/xenapi-datamodel-graph.dot	Thu Aug 07 11:47:34 2008 +0900
    14.2 +++ b/docs/xen-api/xenapi-datamodel-graph.dot	Thu Aug 07 11:57:34 2008 +0900
    14.3 @@ -14,7 +14,7 @@ fontname="Verdana";
    14.4  
    14.5  node [ shape=box ]; session VM host network VIF PIF SR VDI VBD PBD user XSPolicy ACMPolicy;
    14.6  node [shape=ellipse]; PIF_metrics VIF_metrics VM_metrics VBD_metrics PBD_metrics VM_guest_metrics host_metrics;
    14.7 -node [shape=box]; host_cpu console
    14.8 +node [shape=box]; DPCI PPCI host_cpu console
    14.9  session -> host [ arrowhead="none" ]
   14.10  session -> user [ arrowhead="none" ]
   14.11  VM -> VM_metrics [ arrowhead="none" ]
   14.12 @@ -22,7 +22,7 @@ VM -> VM_guest_metrics [ arrowhead="none
   14.13  VM -> console [ arrowhead="crow" ]
   14.14  host -> PBD [ arrowhead="crow", arrowtail="none" ]
   14.15  host -> host_metrics [ arrowhead="none" ]
   14.16 -host -> host_cpu [ arrowhead="none" ]
   14.17 +host -> host_cpu [ arrowhead="crow", arrowtail="none" ]
   14.18  VIF -> VM [ arrowhead="none", arrowtail="crow" ]
   14.19  VIF -> network [ arrowhead="none", arrowtail="crow" ]
   14.20  VIF -> VIF_metrics [ arrowhead="none" ]
   14.21 @@ -38,4 +38,7 @@ VTPM -> VM [ arrowhead="none", arrowtail
   14.22  VBD -> VBD_metrics [ arrowhead="none" ]
   14.23  XSPolicy -> host [ arrowhead="none" ]
   14.24  XSPolicy -> ACMPolicy [ arrowhead="none" ]
   14.25 +DPCI -> VM [ arrowhead="none", arrowtail="crow" ]
   14.26 +DPCI -> PPCI [ arrowhead="none" ]
   14.27 +PPCI -> host [ arrowhead="none", arrowtail="crow" ]
   14.28  }
    15.1 --- a/docs/xen-api/xenapi-datamodel.tex	Thu Aug 07 11:47:34 2008 +0900
    15.2 +++ b/docs/xen-api/xenapi-datamodel.tex	Thu Aug 07 11:57:34 2008 +0900
    15.3 @@ -44,6 +44,8 @@ Name & Description \\
    15.4  {\tt crashdump} & A VM crashdump \\
    15.5  {\tt VTPM} & A virtual TPM device \\
    15.6  {\tt console} & A console \\
    15.7 +{\tt DPCI} & A pass-through PCI device \\
    15.8 +{\tt PPCI} & A physical PCI device \\
    15.9  {\tt user} & A user of the system \\
   15.10  {\tt debug} & A basic class for testing \\
   15.11  {\tt XSPolicy} & A class for handling Xen Security Policies \\
   15.12 @@ -70,6 +72,8 @@ PIF.network & network.PIFs & one-to-many
   15.13  SR.VDIs & VDI.SR & many-to-one\\
   15.14  VTPM.VM & VM.VTPMs & one-to-many\\
   15.15  console.VM & VM.consoles & one-to-many\\
   15.16 +DPCI.VM & VM.DPCIs & one-to-many\\
   15.17 +PPCI.host & host.PPCIs & one-to-many\\
   15.18  host.resident\_VMs & VM.resident\_on & many-to-one\\
   15.19  host.host\_CPUs & host\_cpu.host & many-to-one\\
   15.20  \hline
   15.21 @@ -1402,6 +1406,7 @@ Quals & Field & Type & Description \\
   15.22  $\mathit{RO}_\mathit{run}$ &  {\tt VBDs} & (VBD ref) Set & virtual block devices \\
   15.23  $\mathit{RO}_\mathit{run}$ &  {\tt crash\_dumps} & (crashdump ref) Set & crash dumps associated with this VM \\
   15.24  $\mathit{RO}_\mathit{run}$ &  {\tt VTPMs} & (VTPM ref) Set & virtual TPMs \\
   15.25 +$\mathit{RO}_\mathit{run}$ &  {\tt DPCIs} & (DPCI ref) Set & pass-through PCI devices \\
   15.26  $\mathit{RW}$ &  {\tt PV/bootloader} & string & name of or path to bootloader \\
   15.27  $\mathit{RW}$ &  {\tt PV/kernel} & string & path to the kernel \\
   15.28  $\mathit{RW}$ &  {\tt PV/ramdisk} & string & path to the initrd \\
   15.29 @@ -3413,6 +3418,38 @@ value of the field
   15.30  \vspace{0.3cm}
   15.31  \vspace{0.3cm}
   15.32  \vspace{0.3cm}
   15.33 +\subsubsection{RPC name:~get\_DPCIs}
   15.34 +
   15.35 +{\bf Overview:} 
   15.36 +Get the DPCIs field of the given VM.
   15.37 +
   15.38 + \noindent {\bf Signature:} 
   15.39 +\begin{verbatim} ((DPCI ref) Set) get_DPCIs (session_id s, VM ref self)\end{verbatim}
   15.40 +
   15.41 +
   15.42 +\noindent{\bf Arguments:}
   15.43 +
   15.44 + 
   15.45 +\vspace{0.3cm}
   15.46 +\begin{tabular}{|c|c|p{7cm}|}
   15.47 + \hline
   15.48 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   15.49 +{\tt VM ref } & self & reference to the object \\ \hline 
   15.50 +
   15.51 +\end{tabular}
   15.52 +
   15.53 +\vspace{0.3cm}
   15.54 +
   15.55 + \noindent {\bf Return Type:} 
   15.56 +{\tt 
   15.57 +(DPCI ref) Set
   15.58 +}
   15.59 +
   15.60 +
   15.61 +value of the field
   15.62 +\vspace{0.3cm}
   15.63 +\vspace{0.3cm}
   15.64 +\vspace{0.3cm}
   15.65  \subsubsection{RPC name:~get\_PV\_bootloader}
   15.66  
   15.67  {\bf Overview:} 
   15.68 @@ -5480,6 +5517,7 @@ Quals & Field & Type & Description \\
   15.69  $\mathit{RW}$ &  {\tt suspend\_image\_sr} & SR ref & The SR in which VDIs for suspend images are created \\
   15.70  $\mathit{RW}$ &  {\tt crash\_dump\_sr} & SR ref & The SR in which VDIs for crash dumps are created \\
   15.71  $\mathit{RO}_\mathit{run}$ &  {\tt PBDs} & (PBD ref) Set & physical blockdevices \\
   15.72 +$\mathit{RO}_\mathit{run}$ &  {\tt PPCIs} & (PPCI ref) Set & physical PCI devices \\
   15.73  $\mathit{RO}_\mathit{run}$ &  {\tt host\_CPUs} & (host\_cpu ref) Set & The physical CPUs on this host \\
   15.74  $\mathit{RO}_\mathit{run}$ &  {\tt metrics} & host\_metrics ref & metrics associated with this host \\
   15.75  \hline
   15.76 @@ -6774,6 +6812,38 @@ value of the field
   15.77  \vspace{0.3cm}
   15.78  \vspace{0.3cm}
   15.79  \vspace{0.3cm}
   15.80 +\subsubsection{RPC name:~get\_PPCIs}
   15.81 +
   15.82 +{\bf Overview:} 
   15.83 +Get the PPCIs field of the given host.
   15.84 +
   15.85 + \noindent {\bf Signature:} 
   15.86 +\begin{verbatim} ((PPCI ref) Set) get_PPCIs (session_id s, host ref self)\end{verbatim}
   15.87 +
   15.88 +
   15.89 +\noindent{\bf Arguments:}
   15.90 +
   15.91 + 
   15.92 +\vspace{0.3cm}
   15.93 +\begin{tabular}{|c|c|p{7cm}|}
   15.94 + \hline
   15.95 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   15.96 +{\tt host ref } & self & reference to the object \\ \hline 
   15.97 +
   15.98 +\end{tabular}
   15.99 +
  15.100 +\vspace{0.3cm}
  15.101 +
  15.102 + \noindent {\bf Return Type:} 
  15.103 +{\tt 
  15.104 +(PPCI ref) Set
  15.105 +}
  15.106 +
  15.107 +
  15.108 +value of the field
  15.109 +\vspace{0.3cm}
  15.110 +\vspace{0.3cm}
  15.111 +\vspace{0.3cm}
  15.112  \subsubsection{RPC name:~get\_host\_CPUs}
  15.113  
  15.114  {\bf Overview:} 
  15.115 @@ -14464,6 +14534,1195 @@ all fields from the object
  15.116  
  15.117  \vspace{1cm}
  15.118  \newpage
  15.119 +\section{Class: DPCI}
  15.120 +\subsection{Fields for class: DPCI}
  15.121 +\begin{longtable}{|lllp{0.38\textwidth}|}
  15.122 +\hline
  15.123 +\multicolumn{1}{|l}{Name} & \multicolumn{3}{l|}{\bf DPCI} \\
  15.124 +\multicolumn{1}{|l}{Description} & \multicolumn{3}{l|}{\parbox{11cm}{\em A
  15.125 +pass-through PCI device.}} \\
  15.126 +\hline
  15.127 +Quals & Field & Type & Description \\
  15.128 +\hline
  15.129 +$\mathit{RO}_\mathit{run}$ &  {\tt uuid} & string & unique identifier/object reference \\
  15.130 +$\mathit{RO}_\mathit{inst}$ &  {\tt VM} & VM ref & the virtual machine \\
  15.131 +$\mathit{RO}_\mathit{inst}$ &  {\tt PPCI} & PPCI ref & the physical PCI device \\
  15.132 +$\mathit{RO}_\mathit{inst}$ &  {\tt hotplug\_slot} & int & the slot number to which this PCI device is inserted \\
  15.133 +$\mathit{RO}_\mathit{run}$ &  {\tt virtual\_domain} & int & the virtual domain number \\
  15.134 +$\mathit{RO}_\mathit{run}$ &  {\tt virtual\_bus} & int & the virtual bus number \\
  15.135 +$\mathit{RO}_\mathit{run}$ &  {\tt virtual\_slot} & int & the virtual slot number \\
  15.136 +$\mathit{RO}_\mathit{run}$ &  {\tt virtual\_func} & int & the virtual func number \\
  15.137 +$\mathit{RO}_\mathit{run}$ &  {\tt virtual\_name} & string & the virtual PCI name \\
  15.138 +\hline
  15.139 +\end{longtable}
  15.140 +\subsection{RPCs associated with class: DPCI}
  15.141 +\subsubsection{RPC name:~get\_all}
  15.142 +
  15.143 +{\bf Overview:} 
  15.144 +Return a list of all the DPCIs known to the system.
  15.145 +
  15.146 + \noindent {\bf Signature:} 
  15.147 +\begin{verbatim} ((DPCI ref) Set) get_all (session_id s)\end{verbatim}
  15.148 +
  15.149 +
  15.150 +\vspace{0.3cm}
  15.151 +
  15.152 + \noindent {\bf Return Type:} 
  15.153 +{\tt 
  15.154 +(DPCI ref) Set
  15.155 +}
  15.156 +
  15.157 +
  15.158 +references to all objects
  15.159 +\vspace{0.3cm}
  15.160 +\vspace{0.3cm}
  15.161 +\vspace{0.3cm}
  15.162 +\subsubsection{RPC name:~get\_uuid}
  15.163 +
  15.164 +{\bf Overview:} 
  15.165 +Get the uuid field of the given DPCI.
  15.166 +
  15.167 + \noindent {\bf Signature:} 
  15.168 +\begin{verbatim} string get_uuid (session_id s, DPCI ref self)\end{verbatim}
  15.169 +
  15.170 +
  15.171 +\noindent{\bf Arguments:}
  15.172 +
  15.173 + 
  15.174 +\vspace{0.3cm}
  15.175 +\begin{tabular}{|c|c|p{7cm}|}
  15.176 + \hline
  15.177 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  15.178 +{\tt DPCI ref } & self & reference to the object \\ \hline 
  15.179 +
  15.180 +\end{tabular}
  15.181 +
  15.182 +\vspace{0.3cm}
  15.183 +
  15.184 + \noindent {\bf Return Type:} 
  15.185 +{\tt 
  15.186 +string
  15.187 +}
  15.188 +
  15.189 +
  15.190 +value of the field
  15.191 +\vspace{0.3cm}
  15.192 +\vspace{0.3cm}
  15.193 +\vspace{0.3cm}
  15.194 +\subsubsection{RPC name:~get\_VM}
  15.195 +
  15.196 +{\bf Overview:} 
  15.197 +Get the VM field of the given DPCI.
  15.198 +
  15.199 + \noindent {\bf Signature:} 
  15.200 +\begin{verbatim} (VM ref) get_VM (session_id s, DPCI ref self)\end{verbatim}
  15.201 +
  15.202 +
  15.203 +\noindent{\bf Arguments:}
  15.204 +
  15.205 + 
  15.206 +\vspace{0.3cm}
  15.207 +\begin{tabular}{|c|c|p{7cm}|}
  15.208 + \hline
  15.209 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  15.210 +{\tt DPCI ref } & self & reference to the object \\ \hline 
  15.211 +
  15.212 +\end{tabular}
  15.213 +
  15.214 +\vspace{0.3cm}
  15.215 +
  15.216 + \noindent {\bf Return Type:} 
  15.217 +{\tt 
  15.218 +VM ref
  15.219 +}
  15.220 +
  15.221 +
  15.222 +value of the field
  15.223 +\vspace{0.3cm}
  15.224 +\vspace{0.3cm}
  15.225 +\vspace{0.3cm}
  15.226 +\subsubsection{RPC name:~get\_PPCI}
  15.227 +
  15.228 +{\bf Overview:} 
  15.229 +Get the PPCI field of the given DPCI.
  15.230 +
  15.231 + \noindent {\bf Signature:} 
  15.232 +\begin{verbatim} (PPCI ref) get_PPCI (session_id s, DPCI ref self)\end{verbatim}
  15.233 +
  15.234 +
  15.235 +\noindent{\bf Arguments:}
  15.236 +
  15.237 + 
  15.238 +\vspace{0.3cm}
  15.239 +\begin{tabular}{|c|c|p{7cm}|}
  15.240 + \hline
  15.241 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  15.242 +{\tt DPCI ref } & self & reference to the object \\ \hline 
  15.243 +
  15.244 +\end{tabular}
  15.245 +
  15.246 +\vspace{0.3cm}
  15.247 +
  15.248 + \noindent {\bf Return Type:} 
  15.249 +{\tt 
  15.250 +PPCI ref
  15.251 +}
  15.252 +
  15.253 +
  15.254 +value of the field
  15.255 +\vspace{0.3cm}
  15.256 +\vspace{0.3cm}
  15.257 +\vspace{0.3cm}
  15.258 +\subsubsection{RPC name:~get\_hotplug\_slot}
  15.259 +
  15.260 +{\bf Overview:} 
  15.261 +Get the hotplug\_slot field of the given DPCI.
  15.262 +
  15.263 + \noindent {\bf Signature:} 
  15.264 +\begin{verbatim} int get_hotplug_slot (session_id s, DPCI ref self)\end{verbatim}
  15.265 +
  15.266 +
  15.267 +\noindent{\bf Arguments:}
  15.268 +
  15.269 + 
  15.270 +\vspace{0.3cm}
  15.271 +\begin{tabular}{|c|c|p{7cm}|}
  15.272 + \hline
  15.273 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  15.274 +{\tt DPCI ref } & self & reference to the object \\ \hline 
  15.275 +
  15.276 +\end{tabular}
  15.277 +
  15.278 +\vspace{0.3cm}
  15.279 +
  15.280 + \noindent {\bf Return Type:} 
  15.281 +{\tt 
  15.282 +int
  15.283 +}
  15.284 +
  15.285 +
  15.286 +value of the field
  15.287 +\vspace{0.3cm}
  15.288 +\vspace{0.3cm}
  15.289 +\vspace{0.3cm}
  15.290 +\subsubsection{RPC name:~get\_virtual\_domain}
  15.291 +
  15.292 +{\bf Overview:} 
  15.293 +Get the virtual\_domain field of the given DPCI.
  15.294 +
  15.295 + \noindent {\bf Signature:} 
  15.296 +\begin{verbatim} int get_virtual_domain (session_id s, DPCI ref self)\end{verbatim}
  15.297 +
  15.298 +
  15.299 +\noindent{\bf Arguments:}
  15.300 +
  15.301 + 
  15.302 +\vspace{0.3cm}
  15.303 +\begin{tabular}{|c|c|p{7cm}|}
  15.304 + \hline
  15.305 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  15.306 +{\tt DPCI ref } & self & reference to the object \\ \hline 
  15.307 +
  15.308 +\end{tabular}
  15.309 +
  15.310 +\vspace{0.3cm}
  15.311 +
  15.312 + \noindent {\bf Return Type:} 
  15.313 +{\tt 
  15.314 +int
  15.315 +}
  15.316 +
  15.317 +
  15.318 +value of the field
  15.319 +\vspace{0.3cm}
  15.320 +\vspace{0.3cm}
  15.321 +\vspace{0.3cm}
  15.322 +\subsubsection{RPC name:~get\_virtual\_bus}
  15.323 +
  15.324 +{\bf Overview:} 
  15.325 +Get the virtual\_bus field of the given DPCI.
  15.326 +
  15.327 + \noindent {\bf Signature:} 
  15.328 +\begin{verbatim} int get_virtual_bus (session_id s, DPCI ref self)\end{verbatim}
  15.329 +
  15.330 +
  15.331 +\noindent{\bf Arguments:}
  15.332 +
  15.333 + 
  15.334 +\vspace{0.3cm}
  15.335 +\begin{tabular}{|c|c|p{7cm}|}
  15.336 + \hline
  15.337 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  15.338 +{\tt DPCI ref } & self & reference to the object \\ \hline 
  15.339 +
  15.340 +\end{tabular}
  15.341 +
  15.342 +\vspace{0.3cm}
  15.343 +
  15.344 + \noindent {\bf Return Type:} 
  15.345 +{\tt 
  15.346 +int
  15.347 +}
  15.348 +
  15.349 +
  15.350 +value of the field
  15.351 +\vspace{0.3cm}
  15.352 +\vspace{0.3cm}
  15.353 +\vspace{0.3cm}
  15.354 +\subsubsection{RPC name:~get\_virtual\_slot}
  15.355 +
  15.356 +{\bf Overview:} 
  15.357 +Get the virtual\_slot field of the given DPCI.
  15.358 +
  15.359 + \noindent {\bf Signature:} 
  15.360 +\begin{verbatim} int get_virtual_slot (session_id s, DPCI ref self)\end{verbatim}
  15.361 +
  15.362 +
  15.363 +\noindent{\bf Arguments:}
  15.364 +
  15.365 + 
  15.366 +\vspace{0.3cm}
  15.367 +\begin{tabular}{|c|c|p{7cm}|}
  15.368 + \hline
  15.369 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  15.370 +{\tt DPCI ref } & self & reference to the object \\ \hline 
  15.371 +
  15.372 +\end{tabular}
  15.373 +
  15.374 +\vspace{0.3cm}
  15.375 +
  15.376 + \noindent {\bf Return Type:} 
  15.377 +{\tt 
  15.378 +int
  15.379 +}
  15.380 +
  15.381 +
  15.382 +value of the field
  15.383 +\vspace{0.3cm}
  15.384 +\vspace{0.3cm}
  15.385 +\vspace{0.3cm}
  15.386 +\subsubsection{RPC name:~get\_virtual\_func}
  15.387 +
  15.388 +{\bf Overview:} 
  15.389 +Get the virtual\_func field of the given DPCI.
  15.390 +
  15.391 + \noindent {\bf Signature:} 
  15.392 +\begin{verbatim} int get_virtual_func (session_id s, DPCI ref self)\end{verbatim}
  15.393 +
  15.394 +
  15.395 +\noindent{\bf Arguments:}
  15.396 +
  15.397 + 
  15.398 +\vspace{0.3cm}
  15.399 +\begin{tabular}{|c|c|p{7cm}|}
  15.400 + \hline
  15.401 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  15.402 +{\tt DPCI ref } & self & reference to the object \\ \hline 
  15.403 +
  15.404 +\end{tabular}
  15.405 +
  15.406 +\vspace{0.3cm}
  15.407 +
  15.408 + \noindent {\bf Return Type:} 
  15.409 +{\tt 
  15.410 +int
  15.411 +}
  15.412 +
  15.413 +
  15.414 +value of the field
  15.415 +\vspace{0.3cm}
  15.416 +\vspace{0.3cm}
  15.417 +\vspace{0.3cm}
  15.418 +\subsubsection{RPC name:~get\_virtual\_name}
  15.419 +
  15.420 +{\bf Overview:} 
  15.421 +Get the virtual\_name field of the given DPCI.
  15.422 +
  15.423 + \noindent {\bf Signature:} 
  15.424 +\begin{verbatim} string get_virtual_name (session_id s, DPCI ref self)\end{verbatim}
  15.425 +
  15.426 +
  15.427 +\noindent{\bf Arguments:}
  15.428 +
  15.429 + 
  15.430 +\vspace{0.3cm}
  15.431 +\begin{tabular}{|c|c|p{7cm}|}
  15.432 + \hline
  15.433 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  15.434 +{\tt DPCI ref } & self & reference to the object \\ \hline 
  15.435 +
  15.436 +\end{tabular}
  15.437 +
  15.438 +\vspace{0.3cm}
  15.439 +
  15.440 + \noindent {\bf Return Type:} 
  15.441 +{\tt 
  15.442 +string
  15.443 +}
  15.444 +
  15.445 +
  15.446 +value of the field
  15.447 +\vspace{0.3cm}
  15.448 +\vspace{0.3cm}
  15.449 +\vspace{0.3cm}
  15.450 +\subsubsection{RPC name:~create}
  15.451 +
  15.452 +{\bf Overview:} 
  15.453 +Create a new DPCI instance, and return its handle.
  15.454 +
  15.455 + \noindent {\bf Signature:} 
  15.456 +\begin{verbatim} (DPCI ref) create (session_id s, DPCI record args)\end{verbatim}
  15.457 +
  15.458 +
  15.459 +\noindent{\bf Arguments:}
  15.460 +
  15.461 + 
  15.462 +\vspace{0.3cm}
  15.463 +\begin{tabular}{|c|c|p{7cm}|}
  15.464 + \hline
  15.465 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  15.466 +{\tt DPCI record } & args & All constructor arguments \\ \hline 
  15.467 +
  15.468 +\end{tabular}
  15.469 +
  15.470 +\vspace{0.3cm}
  15.471 +
  15.472 + \noindent {\bf Return Type:} 
  15.473 +{\tt 
  15.474 +DPCI ref
  15.475 +}
  15.476 +
  15.477 +
  15.478 +reference to the newly created object
  15.479 +\vspace{0.3cm}
  15.480 +\vspace{0.3cm}
  15.481 +\vspace{0.3cm}
  15.482 +\subsubsection{RPC name:~destroy}
  15.483 +
  15.484 +{\bf Overview:} 
  15.485 +Destroy the specified DPCI instance.
  15.486 +
  15.487 + \noindent {\bf Signature:} 
  15.488 +\begin{verbatim} void destroy (session_id s, DPCI ref self)\end{verbatim}
  15.489 +
  15.490 +
  15.491 +\noindent{\bf Arguments:}
  15.492 +
  15.493 + 
  15.494 +\vspace{0.3cm}
  15.495 +\begin{tabular}{|c|c|p{7cm}|}
  15.496 + \hline
  15.497 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  15.498 +{\tt DPCI ref } & self & reference to the object \\ \hline 
  15.499 +
  15.500 +\end{tabular}
  15.501 +
  15.502 +\vspace{0.3cm}
  15.503 +
  15.504 + \noindent {\bf Return Type:} 
  15.505 +{\tt 
  15.506 +void
  15.507 +}
  15.508 +
  15.509 +
  15.510 +\vspace{0.3cm}
  15.511 +\vspace{0.3cm}
  15.512 +\vspace{0.3cm}
  15.513 +\subsubsection{RPC name:~get\_by\_uuid}
  15.514 +
  15.515 +{\bf Overview:} 
  15.516 +Get a reference to the DPCI instance with the specified UUID.
  15.517 +
  15.518 + \noindent {\bf Signature:} 
  15.519 +\begin{verbatim} (DPCI ref) get_by_uuid (session_id s, string uuid)\end{verbatim}
  15.520 +
  15.521 +
  15.522 +\noindent{\bf Arguments:}
  15.523 +
  15.524 + 
  15.525 +\vspace{0.3cm}
  15.526 +\begin{tabular}{|c|c|p{7cm}|}
  15.527 + \hline
  15.528 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  15.529 +{\tt string } & uuid & UUID of object to return \\ \hline 
  15.530 +
  15.531 +\end{tabular}
  15.532 +
  15.533 +\vspace{0.3cm}
  15.534 +
  15.535 + \noindent {\bf Return Type:} 
  15.536 +{\tt 
  15.537 +DPCI ref
  15.538 +}
  15.539 +
  15.540 +
  15.541 +reference to the object
  15.542 +\vspace{0.3cm}
  15.543 +\vspace{0.3cm}
  15.544 +\vspace{0.3cm}
  15.545 +\subsubsection{RPC name:~get\_record}
  15.546 +
  15.547 +{\bf Overview:} 
  15.548 +Get a record containing the current state of the given DPCI.
  15.549 +
  15.550 + \noindent {\bf Signature:} 
  15.551 +\begin{verbatim} (DPCI record) get_record (session_id s, DPCI ref self)\end{verbatim}
  15.552 +
  15.553 +
  15.554 +\noindent{\bf Arguments:}
  15.555 +
  15.556 + 
  15.557 +\vspace{0.3cm}
  15.558 +\begin{tabular}{|c|c|p{7cm}|}
  15.559 + \hline
  15.560 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  15.561 +{\tt DPCI ref } & self & reference to the object \\ \hline 
  15.562 +
  15.563 +\end{tabular}
  15.564 +
  15.565 +\vspace{0.3cm}
  15.566 +
  15.567 + \noindent {\bf Return Type:} 
  15.568 +{\tt 
  15.569 +DPCI record
  15.570 +}
  15.571 +
  15.572 +
  15.573 +all fields from the object
  15.574 +\vspace{0.3cm}
  15.575 +\vspace{0.3cm}
  15.576 +\vspace{0.3cm}
  15.577 +
  15.578 +\vspace{1cm}
  15.579 +\newpage
  15.580 +\section{Class: PPCI}
  15.581 +\subsection{Fields for class: PPCI}
  15.582 +\begin{longtable}{|lllp{0.38\textwidth}|}
  15.583 +\hline
  15.584 +\multicolumn{1}{|l}{Name} & \multicolumn{3}{l|}{\bf PPCI} \\
  15.585 +\multicolumn{1}{|l}{Description} & \multicolumn{3}{l|}{\parbox{11cm}{\em A
  15.586 +physical PCI device.}} \\
  15.587 +\hline
  15.588 +Quals & Field & Type & Description \\
  15.589 +\hline
  15.590 +$\mathit{RO}_\mathit{run}$ &  {\tt uuid} & string & unique identifier/object reference \\
  15.591 +$\mathit{RO}_\mathit{run}$ &  {\tt host} & host ref &  the physical machine to which this PPCI is connected \\
  15.592 +$\mathit{RO}_\mathit{run}$ &  {\tt domain} & int & the domain number \\
  15.593 +$\mathit{RO}_\mathit{run}$ &  {\tt bus} & int & the bus number \\
  15.594 +$\mathit{RO}_\mathit{run}$ &  {\tt slot} & int & the slot number \\
  15.595 +$\mathit{RO}_\mathit{run}$ &  {\tt func} & int & the func number \\
  15.596 +$\mathit{RO}_\mathit{run}$ &  {\tt name} & string & the PCI name \\
  15.597 +$\mathit{RO}_\mathit{run}$ &  {\tt vendor\_id} & int & the vendor ID \\
  15.598 +$\mathit{RO}_\mathit{run}$ &  {\tt vendor\_name} & string & the vendor name \\
  15.599 +$\mathit{RO}_\mathit{run}$ &  {\tt device\_id} & int & the device ID \\
  15.600 +$\mathit{RO}_\mathit{run}$ &  {\tt device\_name} & string & the device name \\
  15.601 +$\mathit{RO}_\mathit{run}$ &  {\tt revision\_id} & int & the revision ID \\
  15.602 +$\mathit{RO}_\mathit{run}$ &  {\tt class\_code} & int & the class code \\
  15.603 +$\mathit{RO}_\mathit{run}$ &  {\tt class\_name} & string & the class name \\
  15.604 +$\mathit{RO}_\mathit{run}$ &  {\tt subsystem\_vendor\_id} & int & the subsystem vendor ID \\
  15.605 +$\mathit{RO}_\mathit{run}$ &  {\tt subsystem\_vendor\_name} & string & the subsystem vendor name \\
  15.606 +$\mathit{RO}_\mathit{run}$ &  {\tt subsystem\_id} & int & the subsystem ID \\
  15.607 +$\mathit{RO}_\mathit{run}$ &  {\tt subsystem\_name} & string & the subsystem name \\
  15.608 +$\mathit{RO}_\mathit{run}$ &  {\tt driver} & string & the driver name \\
  15.609 +\hline
  15.610 +\end{longtable}
  15.611 +\subsection{RPCs associated with class: PPCI}
  15.612 +\subsubsection{RPC name:~get\_all}
  15.613 +
  15.614 +{\bf Overview:} 
  15.615 +Return a list of all the PPCIs known to the system.
  15.616 +
  15.617 + \noindent {\bf Signature:} 
  15.618 +\begin{verbatim} ((PPCI ref) Set) get_all (session_id s)\end{verbatim}
  15.619 +
  15.620 +
  15.621 +\vspace{0.3cm}
  15.622 +
  15.623 + \noindent {\bf Return Type:} 
  15.624 +{\tt 
  15.625 +(PPCI ref) Set
  15.626 +}
  15.627 +
  15.628 +
  15.629 +references to all objects
  15.630 +\vspace{0.3cm}
  15.631 +\vspace{0.3cm}
  15.632 +\vspace{0.3cm}
  15.633 +\subsubsection{RPC name:~get\_uuid}
  15.634 +
  15.635 +{\bf Overview:} 
  15.636 +Get the uuid field of the given PPCI.
  15.637 +
  15.638 + \noindent {\bf Signature:} 
  15.639 +\begin{verbatim} string get_uuid (session_id s, PPCI ref self)\end{verbatim}
  15.640 +
  15.641 +
  15.642 +\noindent{\bf Arguments:}
  15.643 +
  15.644 + 
  15.645 +\vspace{0.3cm}
  15.646 +\begin{tabular}{|c|c|p{7cm}|}
  15.647 + \hline
  15.648 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  15.649 +{\tt PPCI ref } & self & reference to the object \\ \hline 
  15.650 +
  15.651 +\end{tabular}
  15.652 +
  15.653 +\vspace{0.3cm}
  15.654 +
  15.655 + \noindent {\bf Return Type:} 
  15.656 +{\tt 
  15.657 +string
  15.658 +}
  15.659 +
  15.660 +
  15.661 +value of the field
  15.662 +\vspace{0.3cm}
  15.663 +\vspace{0.3cm}
  15.664 +\vspace{0.3cm}
  15.665 +\subsubsection{RPC name:~get\_host}
  15.666 +
  15.667 +{\bf Overview:} 
  15.668 +Get the host field of the given PPCI.
  15.669 +
  15.670 + \noindent {\bf Signature:} 
  15.671 +\begin{verbatim} (host ref) get_host (session_id s, PPCI ref self)\end{verbatim}
  15.672 +
  15.673 +
  15.674 +\noindent{\bf Arguments:}
  15.675 +
  15.676 + 
  15.677 +\vspace{0.3cm}
  15.678 +\begin{tabular}{|c|c|p{7cm}|}
  15.679 + \hline
  15.680 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  15.681 +{\tt PPCI ref } & self & reference to the object \\ \hline 
  15.682 +
  15.683 +\end{tabular}
  15.684 +
  15.685 +\vspace{0.3cm}
  15.686 +
  15.687 + \noindent {\bf Return Type:} 
  15.688 +{\tt 
  15.689 +host ref
  15.690 +}
  15.691 +
  15.692 +
  15.693 +value of the field
  15.694 +\vspace{0.3cm}
  15.695 +\vspace{0.3cm}
  15.696 +\vspace{0.3cm}
  15.697 +\subsubsection{RPC name:~get\_domain}
  15.698 +
  15.699 +{\bf Overview:} 
  15.700 +Get the domain field of the given PPCI.
  15.701 +
  15.702 + \noindent {\bf Signature:} 
  15.703 +\begin{verbatim} int get_domain (session_id s, PPCI ref self)\end{verbatim}
  15.704 +
  15.705 +
  15.706 +\noindent{\bf Arguments:}
  15.707 +
  15.708 + 
  15.709 +\vspace{0.3cm}
  15.710 +\begin{tabular}{|c|c|p{7cm}|}
  15.711 + \hline
  15.712 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  15.713 +{\tt PPCI ref } & self & reference to the object \\ \hline 
  15.714 +
  15.715 +\end{tabular}
  15.716 +
  15.717 +\vspace{0.3cm}
  15.718 +
  15.719 + \noindent {\bf Return Type:} 
  15.720 +{\tt 
  15.721 +int
  15.722 +}
  15.723 +
  15.724 +
  15.725 +value of the field
  15.726 +\vspace{0.3cm}
  15.727 +\vspace{0.3cm}
  15.728 +\vspace{0.3cm}
  15.729 +\subsubsection{RPC name:~get\_bus}
  15.730 +
  15.731 +{\bf Overview:} 
  15.732 +Get the bus field of the given PPCI.
  15.733 +
  15.734 + \noindent {\bf Signature:} 
  15.735 +\begin{verbatim} int get_bus (session_id s, PPCI ref self)\end{verbatim}
  15.736 +
  15.737 +
  15.738 +\noindent{\bf Arguments:}
  15.739 +
  15.740 + 
  15.741 +\vspace{0.3cm}
  15.742 +\begin{tabular}{|c|c|p{7cm}|}
  15.743 + \hline
  15.744 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  15.745 +{\tt PPCI ref } & self & reference to the object \\ \hline 
  15.746 +
  15.747 +\end{tabular}
  15.748 +
  15.749 +\vspace{0.3cm}
  15.750 +
  15.751 + \noindent {\bf Return Type:} 
  15.752 +{\tt 
  15.753 +int
  15.754 +}
  15.755 +
  15.756 +
  15.757 +value of the field
  15.758 +\vspace{0.3cm}
  15.759 +\vspace{0.3cm}
  15.760 +\vspace{0.3cm}
  15.761 +\subsubsection{RPC name:~get\_slot}
  15.762 +
  15.763 +{\bf Overview:} 
  15.764 +Get the slot field of the given PPCI.
  15.765 +
  15.766 + \noindent {\bf Signature:} 
  15.767 +\begin{verbatim} int get_slot (session_id s, PPCI ref self)\end{verbatim}
  15.768 +
  15.769 +
  15.770 +\noindent{\bf Arguments:}
  15.771 +
  15.772 + 
  15.773 +\vspace{0.3cm}
  15.774 +\begin{tabular}{|c|c|p{7cm}|}
  15.775 + \hline
  15.776 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  15.777 +{\tt PPCI ref } & self & reference to the object \\ \hline 
  15.778 +
  15.779 +\end{tabular}
  15.780 +
  15.781 +\vspace{0.3cm}
  15.782 +
  15.783 + \noindent {\bf Return Type:} 
  15.784 +{\tt 
  15.785 +int
  15.786 +}
  15.787 +
  15.788 +
  15.789 +value of the field
  15.790 +\vspace{0.3cm}
  15.791 +\vspace{0.3cm}
  15.792 +\vspace{0.3cm}
  15.793 +\subsubsection{RPC name:~get\_func}
  15.794 +
  15.795 +{\bf Overview:} 
  15.796 +Get the func field of the given PPCI.
  15.797 +
  15.798 + \noindent {\bf Signature:} 
  15.799 +\begin{verbatim} int get_func (session_id s, PPCI ref self)\end{verbatim}
  15.800 +
  15.801 +
  15.802 +\noindent{\bf Arguments:}
  15.803 +
  15.804 + 
  15.805 +\vspace{0.3cm}
  15.806 +\begin{tabular}{|c|c|p{7cm}|}
  15.807 + \hline
  15.808 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  15.809 +{\tt PPCI ref } & self & reference to the object \\ \hline 
  15.810 +
  15.811 +\end{tabular}
  15.812 +
  15.813 +\vspace{0.3cm}
  15.814 +
  15.815 + \noindent {\bf Return Type:} 
  15.816 +{\tt 
  15.817 +int
  15.818 +}
  15.819 +
  15.820 +
  15.821 +value of the field
  15.822 +\vspace{0.3cm}
  15.823 +\vspace{0.3cm}
  15.824 +\vspace{0.3cm}
  15.825 +\subsubsection{RPC name:~get\_name}
  15.826 +
  15.827 +{\bf Overview:} 
  15.828 +Get the name field of the given PPCI.
  15.829 +
  15.830 + \noindent {\bf Signature:} 
  15.831 +\begin{verbatim} string get_name (session_id s, PPCI ref self)\end{verbatim}
  15.832 +
  15.833 +
  15.834 +\noindent{\bf Arguments:}
  15.835 +
  15.836 + 
  15.837 +\vspace{0.3cm}
  15.838 +\begin{tabular}{|c|c|p{7cm}|}
  15.839 + \hline
  15.840 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  15.841 +{\tt PPCI ref } & self & reference to the object \\ \hline 
  15.842 +
  15.843 +\end{tabular}
  15.844 +
  15.845 +\vspace{0.3cm}
  15.846 +
  15.847 + \noindent {\bf Return Type:} 
  15.848 +{\tt 
  15.849 +string
  15.850 +}
  15.851 +
  15.852 +
  15.853 +value of the field
  15.854 +\vspace{0.3cm}
  15.855 +\vspace{0.3cm}
  15.856 +\vspace{0.3cm}
  15.857 +\subsubsection{RPC name:~get\_vendor\_id}
  15.858 +
  15.859 +{\bf Overview:} 
  15.860 +Get the vendor\_id field of the given PPCI.
  15.861 +
  15.862 + \noindent {\bf Signature:} 
  15.863 +\begin{verbatim} int get_vendor_id (session_id s, PPCI ref self)\end{verbatim}
  15.864 +
  15.865 +
  15.866 +\noindent{\bf Arguments:}
  15.867 +
  15.868 + 
  15.869 +\vspace{0.3cm}
  15.870 +\begin{tabular}{|c|c|p{7cm}|}
  15.871 + \hline
  15.872 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  15.873 +{\tt PPCI ref } & self & reference to the object \\ \hline 
  15.874 +
  15.875 +\end{tabular}
  15.876 +
  15.877 +\vspace{0.3cm}
  15.878 +
  15.879 + \noindent {\bf Return Type:} 
  15.880 +{\tt 
  15.881 +int
  15.882 +}
  15.883 +
  15.884 +
  15.885 +value of the field
  15.886 +\vspace{0.3cm}
  15.887 +\vspace{0.3cm}
  15.888 +\vspace{0.3cm}
  15.889 +\subsubsection{RPC name:~get\_vendor\_name}
  15.890 +
  15.891 +{\bf Overview:} 
  15.892 +Get the vendor\_name field of the given PPCI.
  15.893 +
  15.894 + \noindent {\bf Signature:} 
  15.895 +\begin{verbatim} string get_vendor_name (session_id s, PPCI ref self)\end{verbatim}
  15.896 +
  15.897 +
  15.898 +\noindent{\bf Arguments:}
  15.899 +
  15.900 + 
  15.901 +\vspace{0.3cm}
  15.902 +\begin{tabular}{|c|c|p{7cm}|}
  15.903 + \hline
  15.904 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  15.905 +{\tt PPCI ref } & self & reference to the object \\ \hline 
  15.906 +
  15.907 +\end{tabular}
  15.908 +
  15.909 +\vspace{0.3cm}
  15.910 +
  15.911 + \noindent {\bf Return Type:} 
  15.912 +{\tt 
  15.913 +string
  15.914 +}
  15.915 +
  15.916 +
  15.917 +value of the field
  15.918 +\vspace{0.3cm}
  15.919 +\vspace{0.3cm}
  15.920 +\vspace{0.3cm}
  15.921 +\subsubsection{RPC name:~get\_device\_id}
  15.922 +
  15.923 +{\bf Overview:} 
  15.924 +Get the device\_id field of the given PPCI.
  15.925 +
  15.926 + \noindent {\bf Signature:} 
  15.927 +\begin{verbatim} int get_device_id (session_id s, PPCI ref self)\end{verbatim}
  15.928 +
  15.929 +
  15.930 +\noindent{\bf Arguments:}
  15.931 +
  15.932 + 
  15.933 +\vspace{0.3cm}
  15.934 +\begin{tabular}{|c|c|p{7cm}|}
  15.935 + \hline
  15.936 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  15.937 +{\tt PPCI ref } & self & reference to the object \\ \hline 
  15.938 +
  15.939 +\end{tabular}
  15.940 +
  15.941 +\vspace{0.3cm}
  15.942 +
  15.943 + \noindent {\bf Return Type:} 
  15.944 +{\tt 
  15.945 +int
  15.946 +}
  15.947 +
  15.948 +
  15.949 +value of the field
  15.950 +\vspace{0.3cm}
  15.951 +\vspace{0.3cm}
  15.952 +\vspace{0.3cm}
  15.953 +\subsubsection{RPC name:~get\_device\_name}
  15.954 +
  15.955 +{\bf Overview:} 
  15.956 +Get the device\_name field of the given PPCI.
  15.957 +
  15.958 + \noindent {\bf Signature:} 
  15.959 +\begin{verbatim} string get_device_name (session_id s, PPCI ref self)\end{verbatim}
  15.960 +
  15.961 +
  15.962 +\noindent{\bf Arguments:}
  15.963 +
  15.964 + 
  15.965 +\vspace{0.3cm}
  15.966 +\begin{tabular}{|c|c|p{7cm}|}
  15.967 + \hline
  15.968 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  15.969 +{\tt PPCI ref } & self & reference to the object \\ \hline 
  15.970 +
  15.971 +\end{tabular}
  15.972 +
  15.973 +\vspace{0.3cm}
  15.974 +
  15.975 + \noindent {\bf Return Type:} 
  15.976 +{\tt 
  15.977 +string
  15.978 +}
  15.979 +
  15.980 +
  15.981 +value of the field
  15.982 +\vspace{0.3cm}
  15.983 +\vspace{0.3cm}
  15.984 +\vspace{0.3cm}
  15.985 +\subsubsection{RPC name:~get\_revision\_id}
  15.986 +
  15.987 +{\bf Overview:} 
  15.988 +Get the revision\_id field of the given PPCI.
  15.989 +
  15.990 + \noindent {\bf Signature:} 
  15.991 +\begin{verbatim} int get_revision_id (session_id s, PPCI ref self)\end{verbatim}
  15.992 +
  15.993 +
  15.994 +\noindent{\bf Arguments:}
  15.995 +
  15.996 + 
  15.997 +\vspace{0.3cm}
  15.998 +\begin{tabular}{|c|c|p{7cm}|}
  15.999 + \hline
 15.1000 +{\bf type} & {\bf name} & {\bf description} \\ \hline
 15.1001 +{\tt PPCI ref } & self & reference to the object \\ \hline 
 15.1002 +
 15.1003 +\end{tabular}
 15.1004 +
 15.1005 +\vspace{0.3cm}
 15.1006 +
 15.1007 + \noindent {\bf Return Type:} 
 15.1008 +{\tt 
 15.1009 +int
 15.1010 +}
 15.1011 +
 15.1012 +
 15.1013 +value of the field
 15.1014 +\vspace{0.3cm}
 15.1015 +\vspace{0.3cm}
 15.1016 +\vspace{0.3cm}
 15.1017 +\subsubsection{RPC name:~get\_class\_code}
 15.1018 +
 15.1019 +{\bf Overview:} 
 15.1020 +Get the class\_code field of the given PPCI.
 15.1021 +
 15.1022 + \noindent {\bf Signature:} 
 15.1023 +\begin{verbatim} int get_class_code (session_id s, PPCI ref self)\end{verbatim}
 15.1024 +
 15.1025 +
 15.1026 +\noindent{\bf Arguments:}
 15.1027 +
 15.1028 + 
 15.1029 +\vspace{0.3cm}
 15.1030 +\begin{tabular}{|c|c|p{7cm}|}
 15.1031 + \hline
 15.1032 +{\bf type} & {\bf name} & {\bf description} \\ \hline
 15.1033 +{\tt PPCI ref } & self & reference to the object \\ \hline 
 15.1034 +
 15.1035 +\end{tabular}
 15.1036 +
 15.1037 +\vspace{0.3cm}
 15.1038 +
 15.1039 + \noindent {\bf Return Type:} 
 15.1040 +{\tt 
 15.1041 +int
 15.1042 +}
 15.1043 +
 15.1044 +
 15.1045 +value of the field
 15.1046 +\vspace{0.3cm}
 15.1047 +\vspace{0.3cm}
 15.1048 +\vspace{0.3cm}
 15.1049 +\subsubsection{RPC name:~get\_class\_name}
 15.1050 +
 15.1051 +{\bf Overview:} 
 15.1052 +Get the class\_name field of the given PPCI.
 15.1053 +
 15.1054 + \noindent {\bf Signature:} 
 15.1055 +\begin{verbatim} string get_class_name (session_id s, PPCI ref self)\end{verbatim}
 15.1056 +
 15.1057 +
 15.1058 +\noindent{\bf Arguments:}
 15.1059 +
 15.1060 + 
 15.1061 +\vspace{0.3cm}
 15.1062 +\begin{tabular}{|c|c|p{7cm}|}
 15.1063 + \hline
 15.1064 +{\bf type} & {\bf name} & {\bf description} \\ \hline
 15.1065 +{\tt PPCI ref } & self & reference to the object \\ \hline 
 15.1066 +
 15.1067 +\end{tabular}
 15.1068 +
 15.1069 +\vspace{0.3cm}
 15.1070 +
 15.1071 + \noindent {\bf Return Type:} 
 15.1072 +{\tt 
 15.1073 +string
 15.1074 +}
 15.1075 +
 15.1076 +
 15.1077 +value of the field
 15.1078 +\vspace{0.3cm}
 15.1079 +\vspace{0.3cm}
 15.1080 +\vspace{0.3cm}
 15.1081 +\subsubsection{RPC name:~get\_subsystem\_vendor\_id}
 15.1082 +
 15.1083 +{\bf Overview:} 
 15.1084 +Get the subsystem\_vendor\_id field of the given PPCI.
 15.1085 +
 15.1086 + \noindent {\bf Signature:} 
 15.1087 +\begin{verbatim} int get_subsystem_vendor_id (session_id s, PPCI ref self)\end{verbatim}
 15.1088 +
 15.1089 +
 15.1090 +\noindent{\bf Arguments:}
 15.1091 +
 15.1092 + 
 15.1093 +\vspace{0.3cm}
 15.1094 +\begin{tabular}{|c|c|p{7cm}|}
 15.1095 + \hline
 15.1096 +{\bf type} & {\bf name} & {\bf description} \\ \hline
 15.1097 +{\tt PPCI ref } & self & reference to the object \\ \hline 
 15.1098 +
 15.1099 +\end{tabular}
 15.1100 +
 15.1101 +\vspace{0.3cm}
 15.1102 +
 15.1103 + \noindent {\bf Return Type:} 
 15.1104 +{\tt 
 15.1105 +int
 15.1106 +}
 15.1107 +
 15.1108 +
 15.1109 +value of the field
 15.1110 +\vspace{0.3cm}
 15.1111 +\vspace{0.3cm}
 15.1112 +\vspace{0.3cm}
 15.1113 +\subsubsection{RPC name:~get\_subsystem\_vendor\_name}
 15.1114 +
 15.1115 +{\bf Overview:} 
 15.1116 +Get the subsystem\_vendor\_name field of the given PPCI.
 15.1117 +
 15.1118 + \noindent {\bf Signature:} 
 15.1119 +\begin{verbatim} string get_subsystem_vendor_name (session_id s, PPCI ref self)\end{verbatim}
 15.1120 +
 15.1121 +
 15.1122 +\noindent{\bf Arguments:}
 15.1123 +
 15.1124 + 
 15.1125 +\vspace{0.3cm}
 15.1126 +\begin{tabular}{|c|c|p{7cm}|}
 15.1127 + \hline
 15.1128 +{\bf type} & {\bf name} & {\bf description} \\ \hline
 15.1129 +{\tt PPCI ref } & self & reference to the object \\ \hline 
 15.1130 +
 15.1131 +\end{tabular}
 15.1132 +
 15.1133 +\vspace{0.3cm}
 15.1134 +
 15.1135 + \noindent {\bf Return Type:} 
 15.1136 +{\tt 
 15.1137 +string
 15.1138 +}
 15.1139 +
 15.1140 +
 15.1141 +value of the field
 15.1142 +\vspace{0.3cm}
 15.1143 +\vspace{0.3cm}
 15.1144 +\vspace{0.3cm}
 15.1145 +\subsubsection{RPC name:~get\_subsystem\_id}
 15.1146 +
 15.1147 +{\bf Overview:} 
 15.1148 +Get the subsystem\_id field of the given PPCI.
 15.1149 +
 15.1150 + \noindent {\bf Signature:} 
 15.1151 +\begin{verbatim} int get_subsystem_id (session_id s, PPCI ref self)\end{verbatim}
 15.1152 +
 15.1153 +
 15.1154 +\noindent{\bf Arguments:}
 15.1155 +
 15.1156 + 
 15.1157 +\vspace{0.3cm}
 15.1158 +\begin{tabular}{|c|c|p{7cm}|}
 15.1159 + \hline
 15.1160 +{\bf type} & {\bf name} & {\bf description} \\ \hline
 15.1161 +{\tt PPCI ref } & self & reference to the object \\ \hline 
 15.1162 +
 15.1163 +\end{tabular}
 15.1164 +
 15.1165 +\vspace{0.3cm}
 15.1166 +
 15.1167 + \noindent {\bf Return Type:} 
 15.1168 +{\tt 
 15.1169 +int
 15.1170 +}
 15.1171 +
 15.1172 +
 15.1173 +value of the field
 15.1174 +\vspace{0.3cm}
 15.1175 +\vspace{0.3cm}
 15.1176 +\vspace{0.3cm}
 15.1177 +\subsubsection{RPC name:~get\_subsystem\_name}
 15.1178 +
 15.1179 +{\bf Overview:} 
 15.1180 +Get the subsystem\_name field of the given PPCI.
 15.1181 +
 15.1182 + \noindent {\bf Signature:} 
 15.1183 +\begin{verbatim} string get_subsystem_name (session_id s, PPCI ref self)\end{verbatim}
 15.1184 +
 15.1185 +
 15.1186 +\noindent{\bf Arguments:}
 15.1187 +
 15.1188 + 
 15.1189 +\vspace{0.3cm}
 15.1190 +\begin{tabular}{|c|c|p{7cm}|}
 15.1191 + \hline
 15.1192 +{\bf type} & {\bf name} & {\bf description} \\ \hline
 15.1193 +{\tt PPCI ref } & self & reference to the object \\ \hline 
 15.1194 +
 15.1195 +\end{tabular}
 15.1196 +
 15.1197 +\vspace{0.3cm}
 15.1198 +
 15.1199 + \noindent {\bf Return Type:} 
 15.1200 +{\tt 
 15.1201 +string
 15.1202 +}
 15.1203 +
 15.1204 +
 15.1205 +value of the field
 15.1206 +\vspace{0.3cm}
 15.1207 +\vspace{0.3cm}
 15.1208 +\vspace{0.3cm}
 15.1209 +\subsubsection{RPC name:~get\_driver}
 15.1210 +
 15.1211 +{\bf Overview:} 
 15.1212 +Get the driver field of the given PPCI.
 15.1213 +
 15.1214 + \noindent {\bf Signature:} 
 15.1215 +\begin{verbatim} string get_driver (session_id s, PPCI ref self)\end{verbatim}
 15.1216 +
 15.1217 +
 15.1218 +\noindent{\bf Arguments:}
 15.1219 +
 15.1220 + 
 15.1221 +\vspace{0.3cm}
 15.1222 +\begin{tabular}{|c|c|p{7cm}|}
 15.1223 + \hline
 15.1224 +{\bf type} & {\bf name} & {\bf description} \\ \hline
 15.1225 +{\tt PPCI ref } & self & reference to the object \\ \hline 
 15.1226 +
 15.1227 +\end{tabular}
 15.1228 +
 15.1229 +\vspace{0.3cm}
 15.1230 +
 15.1231 + \noindent {\bf Return Type:} 
 15.1232 +{\tt 
 15.1233 +string
 15.1234 +}
 15.1235 +
 15.1236 +
 15.1237 +value of the field
 15.1238 +\vspace{0.3cm}
 15.1239 +\vspace{0.3cm}
 15.1240 +\vspace{0.3cm}
 15.1241 +\subsubsection{RPC name:~get\_by\_uuid}
 15.1242 +
 15.1243 +{\bf Overview:} 
 15.1244 +Get a reference to the PPCI instance with the specified UUID.
 15.1245 +
 15.1246 + \noindent {\bf Signature:} 
 15.1247 +\begin{verbatim} (PPCI ref) get_by_uuid (session_id s, string uuid)\end{verbatim}
 15.1248 +
 15.1249 +
 15.1250 +\noindent{\bf Arguments:}
 15.1251 +
 15.1252 + 
 15.1253 +\vspace{0.3cm}
 15.1254 +\begin{tabular}{|c|c|p{7cm}|}
 15.1255 + \hline
 15.1256 +{\bf type} & {\bf name} & {\bf description} \\ \hline
 15.1257 +{\tt string } & uuid & UUID of object to return \\ \hline 
 15.1258 +
 15.1259 +\end{tabular}
 15.1260 +
 15.1261 +\vspace{0.3cm}
 15.1262 +
 15.1263 + \noindent {\bf Return Type:} 
 15.1264 +{\tt 
 15.1265 +PPCI ref
 15.1266 +}
 15.1267 +
 15.1268 +
 15.1269 +reference to the object
 15.1270 +\vspace{0.3cm}
 15.1271 +\vspace{0.3cm}
 15.1272 +\vspace{0.3cm}
 15.1273 +\subsubsection{RPC name:~get\_record}
 15.1274 +
 15.1275 +{\bf Overview:} 
 15.1276 +Get a record containing the current state of the given PPCI.
 15.1277 +
 15.1278 + \noindent {\bf Signature:} 
 15.1279 +\begin{verbatim} (PPCI record) get_record (session_id s, PPCI ref self)\end{verbatim}
 15.1280 +
 15.1281 +
 15.1282 +\noindent{\bf Arguments:}
 15.1283 +
 15.1284 + 
 15.1285 +\vspace{0.3cm}
 15.1286 +\begin{tabular}{|c|c|p{7cm}|}
 15.1287 + \hline
 15.1288 +{\bf type} & {\bf name} & {\bf description} \\ \hline
 15.1289 +{\tt PPCI ref } & self & reference to the object \\ \hline 
 15.1290 +
 15.1291 +\end{tabular}
 15.1292 +
 15.1293 +\vspace{0.3cm}
 15.1294 +
 15.1295 + \noindent {\bf Return Type:} 
 15.1296 +{\tt 
 15.1297 +PPCI record
 15.1298 +}
 15.1299 +
 15.1300 +
 15.1301 +all fields from the object
 15.1302 +\vspace{0.3cm}
 15.1303 +\vspace{0.3cm}
 15.1304 +\vspace{0.3cm}
 15.1305 +
 15.1306 +\vspace{1cm}
 15.1307 +\newpage
 15.1308  \section{Class: user}
 15.1309  \subsection{Fields for class: user}
 15.1310  \begin{longtable}{|lllp{0.38\textwidth}|}
    16.1 --- a/extras/mini-os/fs-front.c	Thu Aug 07 11:47:34 2008 +0900
    16.2 +++ b/extras/mini-os/fs-front.c	Thu Aug 07 11:57:34 2008 +0900
    16.3 @@ -50,6 +50,8 @@
    16.4  
    16.5  struct fs_request;
    16.6  struct fs_import *fs_import;
    16.7 +void *alloc_buffer_page(struct fs_request *req, domid_t domid, grant_ref_t *gref);
    16.8 +void free_buffer_page(struct fs_request *req);
    16.9  
   16.10  /******************************************************************************/
   16.11  /*                      RING REQUEST/RESPONSES HANDLING                       */
   16.12 @@ -57,13 +59,21 @@ struct fs_import *fs_import;
   16.13  
   16.14  struct fs_request
   16.15  {
   16.16 -    void *page;
   16.17 -    grant_ref_t gref;
   16.18 +    void *private1;                        /* Specific to request type */
   16.19 +    void *private2;
   16.20      struct thread *thread;                 /* Thread blocked on this request */
   16.21      struct fsif_response shadow_rsp;       /* Response copy writen by the 
   16.22                                                interrupt handler */  
   16.23  };
   16.24  
   16.25 +struct fs_rw_gnts
   16.26 +{
   16.27 +    /* TODO 16 bit? */
   16.28 +    int count;
   16.29 +    grant_ref_t grefs[FSIF_NR_READ_GNTS];  
   16.30 +    void *pages[FSIF_NR_READ_GNTS];  
   16.31 +};
   16.32 +
   16.33  /* Ring operations:
   16.34   * FSIF ring is used differently to Linux-like split devices. This stems from 
   16.35   * the fact that no I/O request queue is present. The use of some of the macros
   16.36 @@ -177,6 +187,8 @@ int fs_open(struct fs_import *import, ch
   16.37  {
   16.38      struct fs_request *fsr;
   16.39      unsigned short priv_req_id;
   16.40 +    grant_ref_t gref;
   16.41 +    void *buffer;
   16.42      RING_IDX back_req_id; 
   16.43      struct fsif_request *req;
   16.44      int fd;
   16.45 @@ -189,14 +201,15 @@ int fs_open(struct fs_import *import, ch
   16.46      priv_req_id = get_id_from_freelist(import->freelist);
   16.47      DEBUG("Request id for fs_open call is: %d\n", priv_req_id);
   16.48      fsr = &import->requests[priv_req_id];
   16.49 -    DEBUG("gref id=%d\n", fsr->gref);
   16.50 +    buffer = alloc_buffer_page(fsr, import->dom_id, &gref);
   16.51 +    DEBUG("gref id=%d\n", gref);
   16.52      fsr->thread = current;
   16.53 -    sprintf(fsr->page, "%s", file);
   16.54 +    sprintf(buffer, "%s", file);
   16.55  
   16.56      req = RING_GET_REQUEST(&import->ring, back_req_id);
   16.57      req->type = REQ_FILE_OPEN;
   16.58      req->id = priv_req_id;
   16.59 -    req->u.fopen.gref = fsr->gref;
   16.60 +    req->u.fopen.gref = gref;
   16.61  
   16.62      /* Set blocked flag before commiting the request, thus avoiding missed
   16.63       * response race */
   16.64 @@ -207,6 +220,7 @@ int fs_open(struct fs_import *import, ch
   16.65      /* Read the response */
   16.66      fd = (int)fsr->shadow_rsp.ret_val;
   16.67      DEBUG("The following FD returned: %d\n", fd);
   16.68 +    free_buffer_page(fsr);
   16.69      add_id_to_freelist(priv_req_id, import->freelist);
   16.70  
   16.71      return fd;
   16.72 @@ -254,11 +268,13 @@ ssize_t fs_read(struct fs_import *import
   16.73  {
   16.74      struct fs_request *fsr;
   16.75      unsigned short priv_req_id;
   16.76 +    struct fs_rw_gnts gnts;
   16.77      RING_IDX back_req_id; 
   16.78      struct fsif_request *req;
   16.79      ssize_t ret;
   16.80 +    int i;
   16.81  
   16.82 -    BUG_ON(len > PAGE_SIZE);
   16.83 +    BUG_ON(len > PAGE_SIZE * FSIF_NR_READ_GNTS);
   16.84  
   16.85      /* Prepare request for the backend */
   16.86      back_req_id = reserve_fsif_request(import);
   16.87 @@ -268,18 +284,28 @@ ssize_t fs_read(struct fs_import *import
   16.88      priv_req_id = get_id_from_freelist(import->freelist);
   16.89      DEBUG("Request id for fs_read call is: %d\n", priv_req_id);
   16.90      fsr = &import->requests[priv_req_id];
   16.91 -    DEBUG("gref=%d\n", fsr->gref);
   16.92 -    fsr->thread = current;
   16.93 -    memset(fsr->page, 0, PAGE_SIZE);
   16.94  
   16.95      req = RING_GET_REQUEST(&import->ring, back_req_id);
   16.96      req->type = REQ_FILE_READ;
   16.97      req->id = priv_req_id;
   16.98      req->u.fread.fd = fd;
   16.99 -    req->u.fread.gref = fsr->gref;
  16.100      req->u.fread.len = len;
  16.101      req->u.fread.offset = offset;
  16.102  
  16.103 +
  16.104 +    ASSERT(len > 0);
  16.105 +    gnts.count = ((len - 1) / PAGE_SIZE) + 1; 
  16.106 +    for(i=0; i<gnts.count; i++)
  16.107 +    {
  16.108 +        gnts.pages[i] = (void *)alloc_page(); 
  16.109 +        gnts.grefs[i] = gnttab_grant_access(import->dom_id, 
  16.110 +                                            virt_to_mfn(gnts.pages[i]), 
  16.111 +                                            0); 
  16.112 +        memset(gnts.pages[i], 0, PAGE_SIZE);
  16.113 +        req->u.fread.grefs[i] = gnts.grefs[i];
  16.114 +    }
  16.115 +    fsr->thread = current;
  16.116 +
  16.117      /* Set blocked flag before commiting the request, thus avoiding missed
  16.118       * response race */
  16.119      block(current);
  16.120 @@ -290,7 +316,19 @@ ssize_t fs_read(struct fs_import *import
  16.121      ret = (ssize_t)fsr->shadow_rsp.ret_val;
  16.122      DEBUG("The following ret value returned %d\n", ret);
  16.123      if(ret > 0)
  16.124 -        memcpy(buf, fsr->page, ret);
  16.125 +    {
  16.126 +        ssize_t to_copy = ret, current_copy;
  16.127 +        for(i=0; i<gnts.count; i++)
  16.128 +        {
  16.129 +            gnttab_end_access(gnts.grefs[i]);
  16.130 +            current_copy = to_copy > PAGE_SIZE ? PAGE_SIZE : to_copy;
  16.131 +            if(current_copy > 0)
  16.132 +                memcpy(buf, gnts.pages[i], current_copy); 
  16.133 +            to_copy -= current_copy; 
  16.134 +            buf = (char*) buf + current_copy;
  16.135 +            free_page(gnts.pages[i]);
  16.136 +        }
  16.137 +    }
  16.138      add_id_to_freelist(priv_req_id, import->freelist);
  16.139  
  16.140      return ret;
  16.141 @@ -301,11 +339,13 @@ ssize_t fs_write(struct fs_import *impor
  16.142  {
  16.143      struct fs_request *fsr;
  16.144      unsigned short priv_req_id;
  16.145 +    struct fs_rw_gnts gnts;
  16.146      RING_IDX back_req_id; 
  16.147      struct fsif_request *req;
  16.148 -    ssize_t ret;
  16.149 +    ssize_t ret, to_copy;
  16.150 +    int i;
  16.151  
  16.152 -    BUG_ON(len > PAGE_SIZE);
  16.153 +    BUG_ON(len > PAGE_SIZE * FSIF_NR_WRITE_GNTS);
  16.154  
  16.155      /* Prepare request for the backend */
  16.156      back_req_id = reserve_fsif_request(import);
  16.157 @@ -315,20 +355,35 @@ ssize_t fs_write(struct fs_import *impor
  16.158      priv_req_id = get_id_from_freelist(import->freelist);
  16.159      DEBUG("Request id for fs_read call is: %d\n", priv_req_id);
  16.160      fsr = &import->requests[priv_req_id];
  16.161 -    DEBUG("gref=%d\n", fsr->gref);
  16.162 -    fsr->thread = current;
  16.163 -    memcpy(fsr->page, buf, len);
  16.164 -    BUG_ON(len > PAGE_SIZE);
  16.165 -    memset((char *)fsr->page + len, 0, PAGE_SIZE - len); 
  16.166  
  16.167      req = RING_GET_REQUEST(&import->ring, back_req_id);
  16.168      req->type = REQ_FILE_WRITE;
  16.169      req->id = priv_req_id;
  16.170      req->u.fwrite.fd = fd;
  16.171 -    req->u.fwrite.gref = fsr->gref;
  16.172      req->u.fwrite.len = len;
  16.173      req->u.fwrite.offset = offset;
  16.174  
  16.175 +    ASSERT(len > 0);
  16.176 +    gnts.count = ((len - 1) / PAGE_SIZE) + 1; 
  16.177 +    to_copy = len;
  16.178 +    for(i=0; i<gnts.count; i++)
  16.179 +    {
  16.180 +        int current_copy = (to_copy > PAGE_SIZE ? PAGE_SIZE : to_copy);
  16.181 +        gnts.pages[i] = (void *)alloc_page(); 
  16.182 +        gnts.grefs[i] = gnttab_grant_access(import->dom_id, 
  16.183 +                                            virt_to_mfn(gnts.pages[i]), 
  16.184 +                                            0); 
  16.185 +        memcpy(gnts.pages[i], buf, current_copy);
  16.186 +        if(current_copy < PAGE_SIZE)
  16.187 +            memset((char *)gnts.pages[i] + current_copy, 
  16.188 +                    0, 
  16.189 +                    PAGE_SIZE - current_copy); 
  16.190 +        req->u.fwrite.grefs[i] = gnts.grefs[i];
  16.191 +        to_copy -= current_copy; 
  16.192 +        buf = (char*) buf + current_copy;
  16.193 +    }
  16.194 +    fsr->thread = current;
  16.195 +
  16.196      /* Set blocked flag before commiting the request, thus avoiding missed
  16.197       * response race */
  16.198      block(current);
  16.199 @@ -338,6 +393,11 @@ ssize_t fs_write(struct fs_import *impor
  16.200      /* Read the response */
  16.201      ret = (ssize_t)fsr->shadow_rsp.ret_val;
  16.202      DEBUG("The following ret value returned %d\n", ret);
  16.203 +    for(i=0; i<gnts.count; i++)
  16.204 +    {
  16.205 +        gnttab_end_access(gnts.grefs[i]);
  16.206 +        free_page(gnts.pages[i]);
  16.207 +    }
  16.208      add_id_to_freelist(priv_req_id, import->freelist);
  16.209  
  16.210      return ret;
  16.211 @@ -361,15 +421,12 @@ int fs_stat(struct fs_import *import,
  16.212      priv_req_id = get_id_from_freelist(import->freelist);
  16.213      DEBUG("Request id for fs_stat call is: %d\n", priv_req_id);
  16.214      fsr = &import->requests[priv_req_id];
  16.215 -    DEBUG("gref=%d\n", fsr->gref);
  16.216      fsr->thread = current;
  16.217 -    memset(fsr->page, 0, PAGE_SIZE);
  16.218  
  16.219      req = RING_GET_REQUEST(&import->ring, back_req_id);
  16.220      req->type = REQ_STAT;
  16.221      req->id = priv_req_id;
  16.222      req->u.fstat.fd   = fd;
  16.223 -    req->u.fstat.gref = fsr->gref;
  16.224  
  16.225      /* Set blocked flag before commiting the request, thus avoiding missed
  16.226       * response race */
  16.227 @@ -380,7 +437,9 @@ int fs_stat(struct fs_import *import,
  16.228      /* Read the response */
  16.229      ret = (int)fsr->shadow_rsp.ret_val;
  16.230      DEBUG("Following ret from fstat: %d\n", ret);
  16.231 -    memcpy(stat, fsr->page, sizeof(struct fsif_stat_response));
  16.232 +    memcpy(stat, 
  16.233 +           &fsr->shadow_rsp.fstat, 
  16.234 +           sizeof(struct fsif_stat_response));
  16.235      add_id_to_freelist(priv_req_id, import->freelist);
  16.236  
  16.237      return ret;
  16.238 @@ -430,6 +489,8 @@ int fs_remove(struct fs_import *import, 
  16.239  {
  16.240      struct fs_request *fsr;
  16.241      unsigned short priv_req_id;
  16.242 +    grant_ref_t gref;
  16.243 +    void *buffer;
  16.244      RING_IDX back_req_id; 
  16.245      struct fsif_request *req;
  16.246      int ret;
  16.247 @@ -442,14 +503,15 @@ int fs_remove(struct fs_import *import, 
  16.248      priv_req_id = get_id_from_freelist(import->freelist);
  16.249      DEBUG("Request id for fs_open call is: %d\n", priv_req_id);
  16.250      fsr = &import->requests[priv_req_id];
  16.251 -    DEBUG("gref=%d\n", fsr->gref);
  16.252 +    buffer = alloc_buffer_page(fsr, import->dom_id, &gref);
  16.253 +    DEBUG("gref=%d\n", gref);
  16.254      fsr->thread = current;
  16.255 -    sprintf(fsr->page, "%s", file);
  16.256 +    sprintf(buffer, "%s", file);
  16.257  
  16.258      req = RING_GET_REQUEST(&import->ring, back_req_id);
  16.259      req->type = REQ_REMOVE;
  16.260      req->id = priv_req_id;
  16.261 -    req->u.fremove.gref = fsr->gref;
  16.262 +    req->u.fremove.gref = gref;
  16.263  
  16.264      /* Set blocked flag before commiting the request, thus avoiding missed
  16.265       * response race */
  16.266 @@ -460,6 +522,7 @@ int fs_remove(struct fs_import *import, 
  16.267      /* Read the response */
  16.268      ret = (int)fsr->shadow_rsp.ret_val;
  16.269      DEBUG("The following ret: %d\n", ret);
  16.270 +    free_buffer_page(fsr);
  16.271      add_id_to_freelist(priv_req_id, import->freelist);
  16.272  
  16.273      return ret;
  16.274 @@ -472,6 +535,8 @@ int fs_rename(struct fs_import *import,
  16.275  {
  16.276      struct fs_request *fsr;
  16.277      unsigned short priv_req_id;
  16.278 +    grant_ref_t gref;
  16.279 +    void *buffer;
  16.280      RING_IDX back_req_id; 
  16.281      struct fsif_request *req;
  16.282      int ret;
  16.283 @@ -486,15 +551,16 @@ int fs_rename(struct fs_import *import,
  16.284      priv_req_id = get_id_from_freelist(import->freelist);
  16.285      DEBUG("Request id for fs_open call is: %d\n", priv_req_id);
  16.286      fsr = &import->requests[priv_req_id];
  16.287 -    DEBUG("gref=%d\n", fsr->gref);
  16.288 +    buffer = alloc_buffer_page(fsr, import->dom_id, &gref);
  16.289 +    DEBUG("gref=%d\n", gref);
  16.290      fsr->thread = current;
  16.291 -    sprintf(fsr->page, "%s%s%c%s%s", 
  16.292 +    sprintf(buffer, "%s%s%c%s%s", 
  16.293              old_header, old_file_name, '\0', new_header, new_file_name);
  16.294  
  16.295      req = RING_GET_REQUEST(&import->ring, back_req_id);
  16.296      req->type = REQ_RENAME;
  16.297      req->id = priv_req_id;
  16.298 -    req->u.frename.gref = fsr->gref;
  16.299 +    req->u.frename.gref = gref;
  16.300      req->u.frename.old_name_offset = strlen(old_header);
  16.301      req->u.frename.new_name_offset = strlen(old_header) +
  16.302                                       strlen(old_file_name) +
  16.303 @@ -511,6 +577,7 @@ int fs_rename(struct fs_import *import,
  16.304      /* Read the response */
  16.305      ret = (int)fsr->shadow_rsp.ret_val;
  16.306      DEBUG("The following ret: %d\n", ret);
  16.307 +    free_buffer_page(fsr);
  16.308      add_id_to_freelist(priv_req_id, import->freelist);
  16.309  
  16.310      return ret;
  16.311 @@ -521,6 +588,8 @@ int fs_create(struct fs_import *import, 
  16.312  {
  16.313      struct fs_request *fsr;
  16.314      unsigned short priv_req_id;
  16.315 +    grant_ref_t gref;
  16.316 +    void *buffer;
  16.317      RING_IDX back_req_id; 
  16.318      struct fsif_request *req;
  16.319      int ret;
  16.320 @@ -533,14 +602,15 @@ int fs_create(struct fs_import *import, 
  16.321      priv_req_id = get_id_from_freelist(import->freelist);
  16.322      DEBUG("Request id for fs_create call is: %d\n", priv_req_id);
  16.323      fsr = &import->requests[priv_req_id];
  16.324 -    DEBUG("gref=%d\n", fsr->gref);
  16.325 +    buffer = alloc_buffer_page(fsr, import->dom_id, &gref);
  16.326 +    DEBUG("gref=%d\n", gref);
  16.327      fsr->thread = current;
  16.328 -    sprintf(fsr->page, "%s", name);
  16.329 +    sprintf(buffer, "%s", name);
  16.330  
  16.331      req = RING_GET_REQUEST(&import->ring, back_req_id);
  16.332      req->type = REQ_CREATE;
  16.333      req->id = priv_req_id;
  16.334 -    req->u.fcreate.gref = fsr->gref;
  16.335 +    req->u.fcreate.gref = gref;
  16.336      req->u.fcreate.directory = directory;
  16.337      req->u.fcreate.mode = mode;
  16.338  
  16.339 @@ -553,6 +623,7 @@ int fs_create(struct fs_import *import, 
  16.340      /* Read the response */
  16.341      ret = (int)fsr->shadow_rsp.ret_val;
  16.342      DEBUG("The following ret: %d\n", ret);
  16.343 +    free_buffer_page(fsr);
  16.344      add_id_to_freelist(priv_req_id, import->freelist);
  16.345  
  16.346      return ret;
  16.347 @@ -563,6 +634,8 @@ char** fs_list(struct fs_import *import,
  16.348  {
  16.349      struct fs_request *fsr;
  16.350      unsigned short priv_req_id;
  16.351 +    grant_ref_t gref;
  16.352 +    void *buffer;
  16.353      RING_IDX back_req_id; 
  16.354      struct fsif_request *req;
  16.355      char **files, *current_file;
  16.356 @@ -579,14 +652,15 @@ char** fs_list(struct fs_import *import,
  16.357      priv_req_id = get_id_from_freelist(import->freelist);
  16.358      DEBUG("Request id for fs_list call is: %d\n", priv_req_id);
  16.359      fsr = &import->requests[priv_req_id];
  16.360 -    DEBUG("gref=%d\n", fsr->gref);
  16.361 +    buffer = alloc_buffer_page(fsr, import->dom_id, &gref);
  16.362 +    DEBUG("gref=%d\n", gref);
  16.363      fsr->thread = current;
  16.364 -    sprintf(fsr->page, "%s", name);
  16.365 +    sprintf(buffer, "%s", name);
  16.366  
  16.367      req = RING_GET_REQUEST(&import->ring, back_req_id);
  16.368      req->type = REQ_DIR_LIST;
  16.369      req->id = priv_req_id;
  16.370 -    req->u.flist.gref = fsr->gref;
  16.371 +    req->u.flist.gref = gref;
  16.372      req->u.flist.offset = offset;
  16.373  
  16.374      /* Set blocked flag before commiting the request, thus avoiding missed
  16.375 @@ -600,7 +674,7 @@ char** fs_list(struct fs_import *import,
  16.376      files = NULL;
  16.377      if(*nr_files <= 0) goto exit;
  16.378      files = malloc(sizeof(char*) * (*nr_files));
  16.379 -    current_file = fsr->page;
  16.380 +    current_file = buffer; 
  16.381      for(i=0; i<*nr_files; i++)
  16.382      {
  16.383          files[i] = strdup(current_file); 
  16.384 @@ -608,6 +682,7 @@ char** fs_list(struct fs_import *import,
  16.385      }
  16.386      if(has_more != NULL)
  16.387          *has_more = fsr->shadow_rsp.ret_val & HAS_MORE_FLAG;
  16.388 +    free_buffer_page(fsr);
  16.389      add_id_to_freelist(priv_req_id, import->freelist);
  16.390  exit:
  16.391      return files;
  16.392 @@ -655,6 +730,8 @@ int64_t fs_space(struct fs_import *impor
  16.393  {
  16.394      struct fs_request *fsr;
  16.395      unsigned short priv_req_id;
  16.396 +    grant_ref_t gref;
  16.397 +    void *buffer;
  16.398      RING_IDX back_req_id; 
  16.399      struct fsif_request *req;
  16.400      int64_t ret;
  16.401 @@ -667,14 +744,15 @@ int64_t fs_space(struct fs_import *impor
  16.402      priv_req_id = get_id_from_freelist(import->freelist);
  16.403      DEBUG("Request id for fs_space is: %d\n", priv_req_id);
  16.404      fsr = &import->requests[priv_req_id];
  16.405 -    DEBUG("gref=%d\n", fsr->gref);
  16.406 +    buffer = alloc_buffer_page(fsr, import->dom_id, &gref);
  16.407 +    DEBUG("gref=%d\n", gref);
  16.408      fsr->thread = current;
  16.409 -    sprintf(fsr->page, "%s", location);
  16.410 +    sprintf(buffer, "%s", location);
  16.411  
  16.412      req = RING_GET_REQUEST(&import->ring, back_req_id);
  16.413      req->type = REQ_FS_SPACE;
  16.414      req->id = priv_req_id;
  16.415 -    req->u.fspace.gref = fsr->gref;
  16.416 +    req->u.fspace.gref = gref;
  16.417  
  16.418      /* Set blocked flag before commiting the request, thus avoiding missed
  16.419       * response race */
  16.420 @@ -685,6 +763,7 @@ int64_t fs_space(struct fs_import *impor
  16.421      /* Read the response */
  16.422      ret = (int64_t)fsr->shadow_rsp.ret_val;
  16.423      DEBUG("The following returned: %lld\n", ret);
  16.424 +    free_buffer_page(fsr);
  16.425      add_id_to_freelist(priv_req_id, import->freelist);
  16.426  
  16.427      return ret;
  16.428 @@ -732,6 +811,23 @@ int fs_sync(struct fs_import *import, in
  16.429  /*                       END OF INDIVIDUAL FILE OPERATIONS                    */
  16.430  /******************************************************************************/
  16.431  
  16.432 +void *alloc_buffer_page(struct fs_request *req, domid_t domid, grant_ref_t *gref)
  16.433 +{
  16.434 +    void *page;
  16.435 +
  16.436 +    page = (void *)alloc_page(); 
  16.437 +    *gref = gnttab_grant_access(domid, virt_to_mfn(page), 0); 
  16.438 +    req->private1 = page;
  16.439 +    req->private2 = (void *)(uintptr_t)(*gref);
  16.440 +
  16.441 +    return page;
  16.442 +}
  16.443 +
  16.444 +void free_buffer_page(struct fs_request *req)
  16.445 +{
  16.446 +    gnttab_end_access((grant_ref_t)(uintptr_t)req->private2);
  16.447 +    free_page(req->private1);
  16.448 +}
  16.449  
  16.450  static void fsfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
  16.451  {
  16.452 @@ -797,15 +893,7 @@ static void alloc_request_table(struct f
  16.453      import->freelist = xmalloc_array(unsigned short, import->nr_entries + 1);
  16.454      memset(import->freelist, 0, sizeof(unsigned short) * (import->nr_entries + 1));
  16.455      for(i=0; i<import->nr_entries; i++)
  16.456 -    {
  16.457 -	/* TODO: that's a lot of memory */
  16.458 -        requests[i].page = (void *)alloc_page(); 
  16.459 -        requests[i].gref = gnttab_grant_access(import->dom_id, 
  16.460 -                                               virt_to_mfn(requests[i].page),
  16.461 -                                               0);
  16.462 -        //printk("   ===>> Page=%lx, gref=%d, mfn=%lx\n", requests[i].page, requests[i].gref, virt_to_mfn(requests[i].page));
  16.463          add_id_to_freelist(i, import->freelist);
  16.464 -    }
  16.465      import->requests = requests;
  16.466  }
  16.467  
  16.468 @@ -818,22 +906,27 @@ static void alloc_request_table(struct f
  16.469  void test_fs_import(void *data)
  16.470  {
  16.471      struct fs_import *import = (struct fs_import *)data; 
  16.472 -    int ret, fd, i;
  16.473 +    int ret, fd, i, repeat_count;
  16.474      int32_t nr_files;
  16.475      char buffer[1024];
  16.476      ssize_t offset;
  16.477      char **files;
  16.478      long ret64;
  16.479 -   
  16.480 +    struct fsif_stat_response stat;
  16.481 +    
  16.482 +    repeat_count = 10; 
  16.483      /* Sleep for 1s and then try to open a file */
  16.484      msleep(1000);
  16.485 +again:
  16.486      ret = fs_create(import, "mini-os-created-directory", 1, 0777);
  16.487      printk("Directory create: %d\n", ret);
  16.488  
  16.489 -    ret = fs_create(import, "mini-os-created-directory/mini-os-created-file", 0, 0666);
  16.490 +    sprintf(buffer, "mini-os-created-directory/mini-os-created-file-%d", 
  16.491 +            repeat_count);
  16.492 +    ret = fs_create(import, buffer, 0, 0666);
  16.493      printk("File create: %d\n", ret);
  16.494  
  16.495 -    fd = fs_open(import, "mini-os-created-directory/mini-os-created-file");
  16.496 +    fd = fs_open(import, buffer);
  16.497      printk("File descriptor: %d\n", fd);
  16.498      if(fd < 0) return;
  16.499  
  16.500 @@ -847,7 +940,16 @@ void test_fs_import(void *data)
  16.501              return;
  16.502          offset += ret;
  16.503      }
  16.504 -
  16.505 +    ret = fs_stat(import, fd, &stat);
  16.506 +    printk("Ret after stat: %d\n", ret);
  16.507 +    printk(" st_mode=%o\n", stat.stat_mode);
  16.508 +    printk(" st_uid =%d\n", stat.stat_uid);
  16.509 +    printk(" st_gid =%d\n", stat.stat_gid);
  16.510 +    printk(" st_size=%ld\n", stat.stat_size);
  16.511 +    printk(" st_atime=%ld\n", stat.stat_atime);
  16.512 +    printk(" st_mtime=%ld\n", stat.stat_mtime);
  16.513 +    printk(" st_ctime=%ld\n", stat.stat_ctime);
  16.514 + 
  16.515      ret = fs_close(import, fd);
  16.516      printk("Closed fd: %d, ret=%d\n", fd, ret);
  16.517     
  16.518 @@ -858,6 +960,9 @@ void test_fs_import(void *data)
  16.519  
  16.520      ret64 = fs_space(import, "/");
  16.521      printk("Free space: %lld (=%lld Mb)\n", ret64, (ret64 >> 20));
  16.522 +    repeat_count--;
  16.523 +    if(repeat_count > 0)
  16.524 +        goto again;
  16.525      
  16.526  }
  16.527  
  16.528 @@ -924,20 +1029,21 @@ static int init_fs_import(struct fs_impo
  16.529      xenbus_transaction_t xbt;
  16.530      char nodename[1024], r_nodename[1024], token[128], *message = NULL;
  16.531      struct fsif_sring *sring;
  16.532 -    int retry = 0;
  16.533 +    int i, retry = 0;
  16.534      domid_t self_id;
  16.535      xenbus_event_queue events = NULL;
  16.536  
  16.537      printk("Initialising FS fortend to backend dom %d\n", import->dom_id);
  16.538      /* Allocate page for the shared ring */
  16.539 -    sring = (struct fsif_sring*) alloc_page();
  16.540 -    memset(sring, 0, PAGE_SIZE);
  16.541 +    sring = (struct fsif_sring*) alloc_pages(FSIF_RING_SIZE_ORDER);
  16.542 +    memset(sring, 0, PAGE_SIZE * FSIF_RING_SIZE_PAGES);
  16.543  
  16.544      /* Init the shared ring */
  16.545      SHARED_RING_INIT(sring);
  16.546 +    ASSERT(FSIF_NR_READ_GNTS == FSIF_NR_WRITE_GNTS);
  16.547  
  16.548      /* Init private frontend ring */
  16.549 -    FRONT_RING_INIT(&import->ring, sring, PAGE_SIZE);
  16.550 +    FRONT_RING_INIT(&import->ring, sring, PAGE_SIZE * FSIF_RING_SIZE_PAGES);
  16.551      import->nr_entries = import->ring.nr_ents;
  16.552  
  16.553      /* Allocate table of requests */
  16.554 @@ -945,7 +1051,11 @@ static int init_fs_import(struct fs_impo
  16.555      init_SEMAPHORE(&import->reqs_sem, import->nr_entries);
  16.556  
  16.557      /* Grant access to the shared ring */
  16.558 -    import->gnt_ref = gnttab_grant_access(import->dom_id, virt_to_mfn(sring), 0);
  16.559 +    for(i=0; i<FSIF_RING_SIZE_PAGES; i++) 
  16.560 +        import->gnt_refs[i] = 
  16.561 +            gnttab_grant_access(import->dom_id, 
  16.562 +                                virt_to_mfn((char *)sring + i * PAGE_SIZE), 
  16.563 +                                0);
  16.564     
  16.565      /* Allocate event channel */ 
  16.566      BUG_ON(evtchn_alloc_unbound(import->dom_id, 
  16.567 @@ -969,13 +1079,27 @@ again:
  16.568      
  16.569      err = xenbus_printf(xbt, 
  16.570                          nodename, 
  16.571 -                        "ring-ref",
  16.572 +                        "ring-size",
  16.573                          "%u",
  16.574 -                        import->gnt_ref);
  16.575 +                        FSIF_RING_SIZE_PAGES);
  16.576      if (err) {
  16.577 -        message = "writing ring-ref";
  16.578 +        message = "writing ring-size";
  16.579          goto abort_transaction;
  16.580      }
  16.581 +    
  16.582 +    for(i=0; i<FSIF_RING_SIZE_PAGES; i++)
  16.583 +    {
  16.584 +        sprintf(r_nodename, "ring-ref-%d", i);
  16.585 +        err = xenbus_printf(xbt, 
  16.586 +                            nodename, 
  16.587 +                            r_nodename,
  16.588 +                            "%u",
  16.589 +                            import->gnt_refs[i]);
  16.590 +        if (err) {
  16.591 +            message = "writing ring-refs";
  16.592 +            goto abort_transaction;
  16.593 +        }
  16.594 +    }
  16.595  
  16.596      err = xenbus_printf(xbt, 
  16.597                          nodename,
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/extras/mini-os/gntmap.c	Thu Aug 07 11:57:34 2008 +0900
    17.3 @@ -0,0 +1,252 @@
    17.4 +/*
    17.5 + * Manages grant mappings from other domains.
    17.6 + *
    17.7 + * Diego Ongaro <diego.ongaro@citrix.com>, July 2008
    17.8 + *
    17.9 + * Files of type FTYPE_GNTMAP contain a gntmap, which is an array of
   17.10 + * (host address, grant handle) pairs. Grant handles come from a hypervisor map
   17.11 + * operation and are needed for the corresponding unmap.
   17.12 + *
   17.13 + * This is a rather naive implementation in terms of performance. If we start
   17.14 + * using it frequently, there's definitely some low-hanging fruit here.
   17.15 + *
   17.16 + *
   17.17 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   17.18 + * of this software and associated documentation files (the "Software"), to
   17.19 + * deal in the Software without restriction, including without limitation the
   17.20 + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
   17.21 + * sell copies of the Software, and to permit persons to whom the Software is
   17.22 + * furnished to do so, subject to the following conditions:
   17.23 + *
   17.24 + * The above copyright notice and this permission notice shall be included in
   17.25 + * all copies or substantial portions of the Software.
   17.26 + *
   17.27 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
   17.28 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
   17.29 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
   17.30 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
   17.31 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
   17.32 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
   17.33 + * DEALINGS IN THE SOFTWARE.
   17.34 + */
   17.35 +
   17.36 +#include <os.h>
   17.37 +#include <xmalloc.h>
   17.38 +#include <errno.h>
   17.39 +#include <xen/grant_table.h>
   17.40 +#include <inttypes.h>
   17.41 +#include "gntmap.h"
   17.42 +
   17.43 +#define DEFAULT_MAX_GRANTS 128
   17.44 +
   17.45 +struct gntmap_entry {
   17.46 +    unsigned long host_addr;
   17.47 +    grant_handle_t handle;
   17.48 +};
   17.49 +
   17.50 +static inline int
   17.51 +gntmap_entry_used(struct gntmap_entry *entry)
   17.52 +{
   17.53 +    return entry->host_addr != 0;
   17.54 +}
   17.55 +
   17.56 +static struct gntmap_entry*
   17.57 +gntmap_find_free_entry(struct gntmap *map)
   17.58 +{
   17.59 +    int i;
   17.60 +
   17.61 +    for (i = 0; i < map->nentries; i++) {
   17.62 +        if (!gntmap_entry_used(&map->entries[i]))
   17.63 +            return &map->entries[i];
   17.64 +    }
   17.65 +
   17.66 +#ifdef GNTMAP_DEBUG
   17.67 +    printk("gntmap_find_free_entry(map=%p): all %d entries full\n",
   17.68 +           map, map->nentries);
   17.69 +#endif
   17.70 +    return NULL;
   17.71 +}
   17.72 +
   17.73 +static struct gntmap_entry*
   17.74 +gntmap_find_entry(struct gntmap *map, unsigned long addr)
   17.75 +{
   17.76 +    int i;
   17.77 +
   17.78 +    for (i = 0; i < map->nentries; i++) {
   17.79 +        if (map->entries[i].host_addr == addr)
   17.80 +            return &map->entries[i];
   17.81 +    }
   17.82 +    return NULL;
   17.83 +}
   17.84 +
   17.85 +int
   17.86 +gntmap_set_max_grants(struct gntmap *map, int count)
   17.87 +{
   17.88 +#ifdef GNTMAP_DEBUG
   17.89 +    printk("gntmap_set_max_grants(map=%p, count=%d)\n", map, count);
   17.90 +#endif
   17.91 +
   17.92 +    if (map->nentries != 0)
   17.93 +        return -EBUSY;
   17.94 +
   17.95 +    map->entries = xmalloc_array(struct gntmap_entry, count);
   17.96 +    if (map->entries == NULL)
   17.97 +        return -ENOMEM;
   17.98 +
   17.99 +    memset(map->entries, 0, sizeof(struct gntmap_entry) * count);
  17.100 +    map->nentries = count;
  17.101 +    return 0;
  17.102 +}
  17.103 +
  17.104 +static int
  17.105 +_gntmap_map_grant_ref(struct gntmap_entry *entry, 
  17.106 +                      unsigned long host_addr,
  17.107 +                      uint32_t domid,
  17.108 +                      uint32_t ref,
  17.109 +                      int writable)
  17.110 +{
  17.111 +    struct gnttab_map_grant_ref op;
  17.112 +    int rc;
  17.113 +
  17.114 +    op.ref = (grant_ref_t) ref;
  17.115 +    op.dom = (domid_t) domid;
  17.116 +    op.host_addr = (uint64_t) host_addr;
  17.117 +    op.flags = GNTMAP_host_map;
  17.118 +    if (!writable)
  17.119 +        op.flags |= GNTMAP_readonly;
  17.120 +
  17.121 +    rc = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
  17.122 +    if (rc != 0 || op.status != GNTST_okay) {
  17.123 +        printk("GNTTABOP_map_grant_ref failed: "
  17.124 +               "returned %d, status %" PRId16 "\n",
  17.125 +               rc, op.status);
  17.126 +        return rc != 0 ? rc : op.status;
  17.127 +    }
  17.128 +
  17.129 +    entry->host_addr = host_addr;
  17.130 +    entry->handle = op.handle;
  17.131 +    return 0;
  17.132 +}
  17.133 +
  17.134 +static int
  17.135 +_gntmap_unmap_grant_ref(struct gntmap_entry *entry)
  17.136 +{
  17.137 +    struct gnttab_unmap_grant_ref op;
  17.138 +    int rc;
  17.139 +
  17.140 +    op.host_addr    = (uint64_t) entry->host_addr;
  17.141 +    op.dev_bus_addr = 0;
  17.142 +    op.handle       = entry->handle;
  17.143 +
  17.144 +    rc = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
  17.145 +    if (rc != 0 || op.status != GNTST_okay) {
  17.146 +        printk("GNTTABOP_unmap_grant_ref failed: "
  17.147 +               "returned %d, status %" PRId16 "\n",
  17.148 +               rc, op.status);
  17.149 +        return rc != 0 ? rc : op.status;
  17.150 +    }
  17.151 +
  17.152 +    entry->host_addr = 0;
  17.153 +    return 0;
  17.154 +}
  17.155 +
  17.156 +int
  17.157 +gntmap_munmap(struct gntmap *map, unsigned long start_address, int count)
  17.158 +{
  17.159 +    int i, rc;
  17.160 +    struct gntmap_entry *ent;
  17.161 +
  17.162 +#ifdef GNTMAP_DEBUG
  17.163 +    printk("gntmap_munmap(map=%p, start_address=%lx, count=%d)\n",
  17.164 +           map, start_address, count);
  17.165 +#endif
  17.166 +
  17.167 +    for (i = 0; i < count; i++) {
  17.168 +        ent = gntmap_find_entry(map, start_address + PAGE_SIZE * i);
  17.169 +        if (ent == NULL) {
  17.170 +            printk("gntmap: tried to munmap unknown page\n");
  17.171 +            return -EINVAL;
  17.172 +        }
  17.173 +
  17.174 +        rc = _gntmap_unmap_grant_ref(ent);
  17.175 +        if (rc != 0)
  17.176 +            return rc;
  17.177 +    }
  17.178 +
  17.179 +    return 0;
  17.180 +}
  17.181 +
  17.182 +void*
  17.183 +gntmap_map_grant_refs(struct gntmap *map, 
  17.184 +                      uint32_t count,
  17.185 +                      uint32_t *domids,
  17.186 +                      int domids_stride,
  17.187 +                      uint32_t *refs,
  17.188 +                      int writable)
  17.189 +{
  17.190 +    unsigned long addr;
  17.191 +    struct gntmap_entry *ent;
  17.192 +    int i;
  17.193 +
  17.194 +#ifdef GNTMAP_DEBUG
  17.195 +    printk("gntmap_map_grant_refs(map=%p, count=%" PRIu32 ", "
  17.196 +           "domids=%p [%" PRIu32 "...], domids_stride=%d, "
  17.197 +           "refs=%p [%" PRIu32 "...], writable=%d)\n",
  17.198 +           map, count,
  17.199 +           domids, domids == NULL ? 0 : domids[0], domids_stride,
  17.200 +           refs, refs == NULL ? 0 : refs[0], writable);
  17.201 +#endif
  17.202 +
  17.203 +    (void) gntmap_set_max_grants(map, DEFAULT_MAX_GRANTS);
  17.204 +
  17.205 +    addr = allocate_ondemand((unsigned long) count, 1);
  17.206 +    if (addr == 0)
  17.207 +        return NULL;
  17.208 +
  17.209 +    for (i = 0; i < count; i++) {
  17.210 +        ent = gntmap_find_free_entry(map);
  17.211 +        if (ent == NULL ||
  17.212 +            _gntmap_map_grant_ref(ent,
  17.213 +                                  addr + PAGE_SIZE * i,
  17.214 +                                  domids[i * domids_stride],
  17.215 +                                  refs[i],
  17.216 +                                  writable) != 0) {
  17.217 +
  17.218 +            (void) gntmap_munmap(map, addr, i);
  17.219 +            return NULL;
  17.220 +        }
  17.221 +    }
  17.222 +
  17.223 +    return (void*) addr;
  17.224 +}
  17.225 +
  17.226 +void
  17.227 +gntmap_init(struct gntmap *map)
  17.228 +{
  17.229 +#ifdef GNTMAP_DEBUG
  17.230 +    printk("gntmap_init(map=%p)\n", map);
  17.231 +#endif
  17.232 +    map->nentries = 0;
  17.233 +    map->entries = NULL;
  17.234 +}
  17.235 +
  17.236 +void
  17.237 +gntmap_fini(struct gntmap *map)
  17.238 +{
  17.239 +    struct gntmap_entry *ent;
  17.240 +    int i;
  17.241 +
  17.242 +#ifdef GNTMAP_DEBUG
  17.243 +    printk("gntmap_fini(map=%p)\n", map);
  17.244 +#endif
  17.245 +
  17.246 +    for (i = 0; i < map->nentries; i++) {
  17.247 +        ent = &map->entries[i];
  17.248 +        if (gntmap_entry_used(ent))
  17.249 +            (void) _gntmap_unmap_grant_ref(ent);
  17.250 +    }
  17.251 +
  17.252 +    xfree(map->entries);
  17.253 +    map->entries = NULL;
  17.254 +    map->nentries = 0;
  17.255 +}
    18.1 --- a/extras/mini-os/include/fs.h	Thu Aug 07 11:47:34 2008 +0900
    18.2 +++ b/extras/mini-os/include/fs.h	Thu Aug 07 11:57:34 2008 +0900
    18.3 @@ -5,6 +5,9 @@
    18.4  #include <mini-os/semaphore.h>
    18.5  #include <mini-os/types.h>
    18.6  
    18.7 +#define FSIF_RING_SIZE_ORDER   1
    18.8 +#define FSIF_RING_SIZE_PAGES   (1<<FSIF_RING_SIZE_ORDER)
    18.9 +
   18.10  struct fs_import 
   18.11  {
   18.12      domid_t dom_id;                 /* dom id of the exporting domain       */ 
   18.13 @@ -14,7 +17,7 @@ struct fs_import
   18.14      unsigned int nr_entries;        /* Number of entries in rings & request
   18.15                                         array                                */
   18.16      struct fsif_front_ring ring;    /* frontend ring (contains shared ring) */
   18.17 -    int gnt_ref;                    /* grant reference to the shared ring   */
   18.18 +    u32 gnt_refs[FSIF_RING_SIZE_PAGES];  /* grant references to the shared ring  */
   18.19      evtchn_port_t local_port;       /* local event channel port             */
   18.20      char *backend;                  /* XenBus location of the backend       */
   18.21      struct fs_request *requests;    /* Table of requests                    */
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/extras/mini-os/include/gntmap.h	Thu Aug 07 11:57:34 2008 +0900
    19.3 @@ -0,0 +1,35 @@
    19.4 +#ifndef __GNTMAP_H__
    19.5 +#define __GNTMAP_H__
    19.6 +
    19.7 +#include <os.h>
    19.8 +
    19.9 +/*
   19.10 + * Please consider struct gntmap opaque. If instead you choose to disregard
   19.11 + * this message, I insist that you keep an eye out for raptors.
   19.12 + */
   19.13 +struct gntmap {
   19.14 +    int nentries;
   19.15 +    struct gntmap_entry *entries;
   19.16 +};
   19.17 +
   19.18 +int
   19.19 +gntmap_set_max_grants(struct gntmap *map, int count);
   19.20 +
   19.21 +int
   19.22 +gntmap_munmap(struct gntmap *map, unsigned long start_address, int count);
   19.23 +
   19.24 +void*
   19.25 +gntmap_map_grant_refs(struct gntmap *map, 
   19.26 +                      uint32_t count,
   19.27 +                      uint32_t *domids,
   19.28 +                      int domids_stride,
   19.29 +                      uint32_t *refs,
   19.30 +                      int writable);
   19.31 +
   19.32 +void
   19.33 +gntmap_init(struct gntmap *map);
   19.34 +
   19.35 +void
   19.36 +gntmap_fini(struct gntmap *map);
   19.37 +
   19.38 +#endif /* !__GNTMAP_H__ */
    20.1 --- a/extras/mini-os/include/lib.h	Thu Aug 07 11:47:34 2008 +0900
    20.2 +++ b/extras/mini-os/include/lib.h	Thu Aug 07 11:57:34 2008 +0900
    20.3 @@ -59,6 +59,7 @@
    20.4  #include <stddef.h>
    20.5  #include <xen/xen.h>
    20.6  #include <xen/event_channel.h>
    20.7 +#include "gntmap.h"
    20.8  
    20.9  #ifdef HAVE_LIBC
   20.10  #include <stdio.h>
   20.11 @@ -138,6 +139,7 @@ enum fd_type {
   20.12      FTYPE_XENBUS,
   20.13      FTYPE_XC,
   20.14      FTYPE_EVTCHN,
   20.15 +    FTYPE_GNTMAP,
   20.16      FTYPE_SOCKET,
   20.17      FTYPE_TAP,
   20.18      FTYPE_BLK,
   20.19 @@ -168,6 +170,7 @@ extern struct file {
   20.20                  int bound;
   20.21              } ports[MAX_EVTCHN_PORTS];
   20.22  	} evtchn;
   20.23 +	struct gntmap gntmap;
   20.24  	struct {
   20.25  	    struct netfront_dev *dev;
   20.26  	} tap;
    21.1 --- a/extras/mini-os/lib/sys.c	Thu Aug 07 11:47:34 2008 +0900
    21.2 +++ b/extras/mini-os/lib/sys.c	Thu Aug 07 11:57:34 2008 +0900
    21.3 @@ -84,6 +84,7 @@
    21.4  #define NOFILE 32
    21.5  extern int xc_evtchn_close(int fd);
    21.6  extern int xc_interface_close(int fd);
    21.7 +extern int xc_gnttab_close(int fd);
    21.8  
    21.9  pthread_mutex_t fd_lock = PTHREAD_MUTEX_INITIALIZER;
   21.10  struct file files[NOFILE] = {
   21.11 @@ -230,8 +231,8 @@ int read(int fd, void *buf, size_t nbyte
   21.12          }
   21.13  	case FTYPE_FILE: {
   21.14  	    ssize_t ret;
   21.15 -	    if (nbytes > PAGE_SIZE)
   21.16 -		nbytes = PAGE_SIZE;
   21.17 +	    if (nbytes > PAGE_SIZE * FSIF_NR_READ_GNTS)
   21.18 +		nbytes = PAGE_SIZE * FSIF_NR_READ_GNTS;
   21.19  	    ret = fs_read(fs_import, files[fd].file.fd, buf, nbytes, files[fd].file.offset);
   21.20  	    if (ret > 0) {
   21.21  		files[fd].file.offset += ret;
   21.22 @@ -291,8 +292,8 @@ int write(int fd, const void *buf, size_
   21.23  	    return nbytes;
   21.24  	case FTYPE_FILE: {
   21.25  	    ssize_t ret;
   21.26 -	    if (nbytes > PAGE_SIZE)
   21.27 -		nbytes = PAGE_SIZE;
   21.28 +	    if (nbytes > PAGE_SIZE * FSIF_NR_WRITE_GNTS)
   21.29 +		nbytes = PAGE_SIZE * FSIF_NR_WRITE_GNTS;
   21.30  	    ret = fs_write(fs_import, files[fd].file.fd, (void *) buf, nbytes, files[fd].file.offset);
   21.31  	    if (ret > 0) {
   21.32  		files[fd].file.offset += ret;
   21.33 @@ -401,6 +402,9 @@ int close(int fd)
   21.34  	case FTYPE_EVTCHN:
   21.35              xc_evtchn_close(fd);
   21.36              return 0;
   21.37 +	case FTYPE_GNTMAP:
   21.38 +	    xc_gnttab_close(fd);
   21.39 +	    return 0;
   21.40  	case FTYPE_TAP:
   21.41  	    shutdown_netfront(files[fd].tap.dev);
   21.42  	    files[fd].type = FTYPE_NONE;
    22.1 --- a/extras/mini-os/minios.mk	Thu Aug 07 11:47:34 2008 +0900
    22.2 +++ b/extras/mini-os/minios.mk	Thu Aug 07 11:57:34 2008 +0900
    22.3 @@ -21,6 +21,7 @@ DEF_CFLAGS += -g
    22.4  #DEF_CFLAGS += -DFS_DEBUG
    22.5  #DEF_CFLAGS += -DLIBC_DEBUG
    22.6  DEF_CFLAGS += -DGNT_DEBUG
    22.7 +DEF_CFLAGS += -DGNTMAP_DEBUG
    22.8  else
    22.9  DEF_CFLAGS += -O3
   22.10  endif
    23.1 --- a/extras/mini-os/pcifront.c	Thu Aug 07 11:47:34 2008 +0900
    23.2 +++ b/extras/mini-os/pcifront.c	Thu Aug 07 11:57:34 2008 +0900
    23.3 @@ -57,6 +57,7 @@ struct pcifront_dev *init_pcifront(char 
    23.4      int retry=0;
    23.5      char* msg;
    23.6      char* nodename = _nodename ? _nodename : "device/pci/0";
    23.7 +    int dom;
    23.8  
    23.9      struct pcifront_dev *dev;
   23.10  
   23.11 @@ -64,12 +65,18 @@ struct pcifront_dev *init_pcifront(char 
   23.12  
   23.13      printk("******************* PCIFRONT for %s **********\n\n\n", nodename);
   23.14  
   23.15 +    snprintf(path, sizeof(path), "%s/backend-id", nodename);
   23.16 +    dom = xenbus_read_integer(path); 
   23.17 +    if (dom == -1) {
   23.18 +        printk("no backend\n");
   23.19 +        return NULL;
   23.20 +    }
   23.21 +
   23.22      dev = malloc(sizeof(*dev));
   23.23      memset(dev, 0, sizeof(*dev));
   23.24      dev->nodename = strdup(nodename);
   23.25 +    dev->dom = dom;
   23.26  
   23.27 -    snprintf(path, sizeof(path), "%s/backend-id", nodename);
   23.28 -    dev->dom = xenbus_read_integer(path); 
   23.29      evtchn_alloc_unbound(dev->dom, pcifront_handler, dev, &dev->evtchn);
   23.30  
   23.31      dev->info = (struct xen_pci_sharedinfo*) alloc_page();
    24.1 --- a/stubdom/Makefile	Thu Aug 07 11:47:34 2008 +0900
    24.2 +++ b/stubdom/Makefile	Thu Aug 07 11:57:34 2008 +0900
    24.3 @@ -3,17 +3,22 @@ MINI_OS = $(XEN_ROOT)/extras/mini-os
    24.4  
    24.5  export XEN_OS=MiniOS
    24.6  
    24.7 -CONFIG_QEMU=ioemu
    24.8 -
    24.9  export stubdom=y
   24.10  export debug=y
   24.11  include $(XEN_ROOT)/Config.mk
   24.12  
   24.13 +override CONFIG_QEMU=ioemu
   24.14 +
   24.15  IOEMU_OPTIONS=--disable-sdl --disable-opengl --disable-gfx-check --disable-vnc-tls --disable-brlapi --disable-kqemu
   24.16 +ZLIB_URL?=http://www.zlib.net
   24.17  ZLIB_VERSION=1.2.3
   24.18 +LIBPCI_URL?=http://www.kernel.org/pub/software/utils/pciutils
   24.19  LIBPCI_VERSION=2.2.9
   24.20 +NEWLIB_URL?=ftp://sources.redhat.com/pub/newlib
   24.21  NEWLIB_VERSION=1.16.0
   24.22 +LWIP_URL?=http://download.savannah.gnu.org/releases/lwip
   24.23  LWIP_VERSION=1.3.0
   24.24 +GRUB_URL?=http://alpha.gnu.org/gnu/grub
   24.25  GRUB_VERSION=0.97
   24.26  
   24.27  WGET=wget -c
   24.28 @@ -75,7 +80,7 @@ endif
   24.29  ##############
   24.30  
   24.31  newlib-$(NEWLIB_VERSION).tar.gz:
   24.32 -	$(WGET) ftp://sources.redhat.com/pub/newlib/$@
   24.33 +	$(WGET) $(NEWLIB_URL)/$@
   24.34  
   24.35  newlib-$(NEWLIB_VERSION): newlib-$(NEWLIB_VERSION).tar.gz
   24.36  	tar xzf $<
   24.37 @@ -97,7 +102,7 @@ cross-newlib: $(NEWLIB_STAMPFILE)
   24.38  ############
   24.39  
   24.40  zlib-$(ZLIB_VERSION).tar.gz:
   24.41 -	$(WGET) http://www.zlib.net/$@
   24.42 +	$(WGET) $(ZLIB_URL)/$@
   24.43  
   24.44  ZLIB_STAMPFILE=$(CROSS_ROOT)/$(GNU_TARGET_ARCH)-xen-elf/lib/libz.a
   24.45  .PHONY: cross-zlib
   24.46 @@ -114,7 +119,7 @@ cross-zlib: $(ZLIB_STAMPFILE)
   24.47  ##############
   24.48  
   24.49  pciutils-$(LIBPCI_VERSION).tar.bz2:
   24.50 -	$(WGET) http://www.kernel.org/pub/software/utils/pciutils/$@
   24.51 +	$(WGET) $(LIBPCI_URL)/$@
   24.52  
   24.53  pciutils-$(LIBPCI_VERSION): pciutils-$(LIBPCI_VERSION).tar.bz2
   24.54  	tar xjf $<
   24.55 @@ -132,7 +137,7 @@ cross-libpci: $(LIBPCI_STAMPFILE)
   24.56  	  $(MAKE) CC="$(CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -I$(realpath $(MINI_OS)/include)" lib/libpci.a && \
   24.57  	  $(INSTALL_DATA) lib/libpci.a $(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf/lib/ && \
   24.58  	  $(INSTALL_DIR) $(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf/include/pci && \
   24.59 -	  $(INSTALL_DATA) lib/{config,header,pci,types}.h $(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf/include/pci/ \
   24.60 +	  $(INSTALL_DATA) lib/config.h lib/header.h lib/pci.h lib/types.h $(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf/include/pci/ \
   24.61  	)
   24.62  
   24.63  ######
   24.64 @@ -140,7 +145,7 @@ cross-libpci: $(LIBPCI_STAMPFILE)
   24.65  ######
   24.66  
   24.67  lwip-$(LWIP_VERSION).tar.gz:
   24.68 -	$(WGET) http://download.savannah.gnu.org/releases/lwip/$@
   24.69 +	$(WGET) $(LWIP_URL)/$@
   24.70  
   24.71  lwip: lwip-$(LWIP_VERSION).tar.gz
   24.72  	tar xzf $<
   24.73 @@ -154,7 +159,6 @@ lwip: lwip-$(LWIP_VERSION).tar.gz
   24.74  .PHONY: $(CROSS_ROOT)
   24.75  $(CROSS_ROOT): cross-newlib cross-zlib cross-libpci
   24.76  
   24.77 -.PHONY: mk-headers
   24.78  mk-headers:
   24.79  	mkdir -p include/xen && \
   24.80            ln -sf $(addprefix ../../,$(wildcard $(XEN_ROOT)/xen/include/public/*.h)) include/xen && \
   24.81 @@ -191,6 +195,7 @@ endif
   24.82  	[ ! -h ioemu/config-host.h ] || rm -f ioemu/config-host.h
   24.83  	[ ! -h ioemu/config-host.mak ] || rm -f ioemu/config-host.mak
   24.84  	$(MAKE) -C $(MINI_OS) links
   24.85 +	touch mk-headers
   24.86  
   24.87  TARGETS_MINIOS=$(addprefix mini-os-,$(TARGETS))
   24.88  $(TARGETS_MINIOS): mini-os-%:
   24.89 @@ -247,7 +252,7 @@ c: $(CROSS_ROOT)
   24.90  ######
   24.91  
   24.92  grub-$(GRUB_VERSION).tar.gz:
   24.93 -	$(WGET) ftp://alpha.gnu.org/gnu/grub/$@
   24.94 +	$(WGET) $(GRUB_URL)/$@
   24.95  
   24.96  grub-upstream: grub-$(GRUB_VERSION).tar.gz
   24.97  	tar xzf $<
   24.98 @@ -291,20 +296,24 @@ pv-grub: mini-os-grub libxc grub
   24.99  #########
  24.100  
  24.101  ifeq ($(STUBDOM_SUPPORTED),1)
  24.102 -install: install-ioemu install-grub
  24.103 +install: install-readme install-ioemu install-grub
  24.104  else
  24.105  install:
  24.106  endif
  24.107  
  24.108 +install-readme:
  24.109 +	$(INSTALL_DIR) $(DESTDIR)$(DOCDIR)
  24.110 +	$(INSTALL_DATA) README $(DESTDIR)$(DOCDIR)/README.stubdom
  24.111 +
  24.112  install-ioemu: ioemu-stubdom
  24.113  	$(INSTALL_DIR) "$(DESTDIR)/usr/lib/xen/bin"
  24.114  	$(INSTALL_PROG) stubdom-dm "$(DESTDIR)/usr/lib/xen/bin"
  24.115  	$(INSTALL_DIR) "$(DESTDIR)/usr/lib/xen/boot"
  24.116 -	$(INSTALL_PROG) mini-os-ioemu/mini-os.gz "$(DESTDIR)/usr/lib/xen/boot/ioemu-stubdom.gz"
  24.117 +	$(INSTALL_DATA) mini-os-ioemu/mini-os.gz "$(DESTDIR)/usr/lib/xen/boot/ioemu-stubdom.gz"
  24.118  
  24.119  install-grub: pv-grub
  24.120  	$(INSTALL_DIR) "$(DESTDIR)/usr/lib/xen/boot"
  24.121 -	$(INSTALL_PROG) mini-os-grub/mini-os.gz "$(DESTDIR)/usr/lib/xen/boot/pv-grub.gz"
  24.122 +	$(INSTALL_DATA) mini-os-grub/mini-os.gz "$(DESTDIR)/usr/lib/xen/boot/pv-grub.gz"
  24.123  
  24.124  #######
  24.125  # clean
  24.126 @@ -320,7 +329,8 @@ clean:
  24.127  	$(MAKE) -C caml clean
  24.128  	$(MAKE) -C c clean
  24.129  	$(MAKE) -C grub clean
  24.130 -	rm -fr libxc ioemu mini-os include
  24.131 +	[ ! -d libxc ] || $(MAKE) -C libxc clean
  24.132 +	[ ! -d ioemu ] || $(MAKE) -C ioemu clean
  24.133  
  24.134  # clean the cross-compilation result
  24.135  .PHONY: crossclean
  24.136 @@ -328,6 +338,8 @@ crossclean: clean
  24.137  	rm -fr $(CROSS_ROOT)
  24.138  	rm -fr newlib-build
  24.139  	rm -fr zlib-$(ZLIB_VERSION) pciutils-$(LIBPCI_VERSION)
  24.140 +	rm -fr libxc ioemu
  24.141 +	rm -f mk-headers
  24.142  
  24.143  # clean patched sources
  24.144  .PHONY: patchclean
    25.1 --- a/stubdom/README	Thu Aug 07 11:47:34 2008 +0900
    25.2 +++ b/stubdom/README	Thu Aug 07 11:57:34 2008 +0900
    25.3 @@ -1,13 +1,3 @@
    25.4 -To compile
    25.5 -==========
    25.6 -
    25.7 -Just run make -j 4, that will download / patch / compile
    25.8 -Then make install to install the result.
    25.9 -
   25.10 -Also, run make and make install in $XEN_ROOT/tools/fs-back
   25.11 -
   25.12 -
   25.13 -
   25.14                                  IOEMU stubdom
   25.15                                  =============
   25.16  
   25.17 @@ -16,6 +6,14 @@ Also, run make and make install in $XEN_
   25.18  General Configuration
   25.19  =====================
   25.20  
   25.21 +Due to a race between the creation of the IOEMU stubdomain itself and allocation
   25.22 +of video memory for the HVM domain, you need to avoid the need for ballooning,
   25.23 +by using the hypervisor dom0_mem= option for instance.
   25.24 +
   25.25 +
   25.26 +There is a sample configuration set in xmexample.hvm-stubdom and
   25.27 +xmexample.hvm-dm
   25.28 +
   25.29  In your HVM config "hvmconfig",
   25.30  
   25.31  - use /usr/lib/xen/bin/stubdom-dm as dm script:
    26.1 --- a/stubdom/stubdom-dm	Thu Aug 07 11:47:34 2008 +0900
    26.2 +++ b/stubdom/stubdom-dm	Thu Aug 07 11:57:34 2008 +0900
    26.3 @@ -55,7 +55,7 @@ term() {
    26.4      kill %1
    26.5      (
    26.6  	[ -n "$vncpid" ] && kill -9 $vncpid
    26.7 -	xm destroy stubdom-$domname
    26.8 +	xm destroy $domname-dm
    26.9  	#xm destroy $domname
   26.10      ) &
   26.11      # We need to exit immediately so as to let xend do the commands above
   26.12 @@ -67,12 +67,12 @@ trap term SIGHUP
   26.13  ############
   26.14  # stubdomain
   26.15  # Wait for any previous stubdom to terminate
   26.16 -while xm list | grep stubdom-$domname
   26.17 +while xm list | grep $domname-dm
   26.18  do
   26.19  	sleep 1
   26.20  done
   26.21  
   26.22 -creation="xm create -c stubdom-$domname target=$domid memory=32 extra=\"$extra\""
   26.23 +creation="xm create -c $domname-dm target=$domid memory=32 extra=\"$extra\""
   26.24  
   26.25  (while true ; do sleep 60 ; done) | /bin/sh -c "$creation" &
   26.26  #xterm -geometry +0+0 -e /bin/sh -c "$creation ; echo ; echo press ENTER to shut down ; read" &
    27.1 --- a/tools/Makefile	Thu Aug 07 11:47:34 2008 +0900
    27.2 +++ b/tools/Makefile	Thu Aug 07 11:57:34 2008 +0900
    27.3 @@ -55,13 +55,14 @@ install: subdirs-install
    27.4  clean distclean: subdirs-clean
    27.5  
    27.6  ifneq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH))
    27.7 -IOEMU_CONFIGURE_CROSS ?= --cross-prefix=$(CROSS_COMPILE) \
    27.8 +IOEMU_CONFIGURE_CROSS ?= --cpu=$(XEN_TARGET_ARCH) \
    27.9 +			 --cross-prefix=$(CROSS_COMPILE) \
   27.10  			 --interp-prefix=$(CROSS_SYS_ROOT)
   27.11  endif
   27.12  
   27.13  ioemu/config-host.mak:
   27.14 -	cd ioemu && XEN_TARGET_ARCH=$(XEN_TARGET_ARCH) sh configure --prefix=/usr \
   27.15 -		$(IOEMU_CONFIGURE_CROSS)
   27.16 +	cd ioemu && XEN_TARGET_ARCH=$(XEN_TARGET_ARCH) sh configure \
   27.17 +		--prefix=$(PREFIX) $(IOEMU_CONFIGURE_CROSS)
   27.18  
   27.19  subdir-all-ioemu subdir-install-ioemu: ioemu/config-host.mak
   27.20  
   27.21 @@ -78,6 +79,12 @@ ioemu-dir-find:
   27.22  			rm -rf ioemu-remote ioemu-remote.tmp; \
   27.23  			mkdir ioemu-remote.tmp; rmdir ioemu-remote.tmp; \
   27.24  			$(GIT) clone $(CONFIG_QEMU) ioemu-remote.tmp; \
   27.25 +			if [ "$(QEMU_TAG)" ]; then			\
   27.26 +				cd ioemu-remote.tmp;			\
   27.27 +				$(GIT) branch -D dummy >/dev/null 2>&1 ||:; \
   27.28 +				$(GIT) checkout -b dummy $(QEMU_TAG);	\
   27.29 +				cd ..;					\
   27.30 +			fi;						\
   27.31  			mv ioemu-remote.tmp ioemu-remote; \
   27.32  		fi; \
   27.33  		rm -f ioemu-dir; \
   27.34 @@ -90,7 +97,7 @@ ioemu-dir-find:
   27.35  		esac; \
   27.36  		export XEN_ROOT; \
   27.37  		cd ioemu-dir; \
   27.38 -		./xen-setup
   27.39 +		./xen-setup $(IOEMU_CONFIGURE_CROSS)
   27.40  
   27.41  subdir-all-ioemu-dir subdir-install-ioemu-dir: ioemu-dir-find
   27.42  
    28.1 --- a/tools/blktap/Makefile	Thu Aug 07 11:47:34 2008 +0900
    28.2 +++ b/tools/blktap/Makefile	Thu Aug 07 11:57:34 2008 +0900
    28.3 @@ -8,3 +8,6 @@ SUBDIRS-y += drivers
    28.4  .PHONY: all clean install
    28.5  all clean install: %: subdirs-%
    28.6  
    28.7 +install:
    28.8 +	$(INSTALL_DIR) $(DESTDIR)$(DOCDIR)
    28.9 +	$(INSTALL_DATA) README $(DESTDIR)$(DOCDIR)/README.blktap
    29.1 --- a/tools/blktap/lib/Makefile	Thu Aug 07 11:47:34 2008 +0900
    29.2 +++ b/tools/blktap/lib/Makefile	Thu Aug 07 11:57:34 2008 +0900
    29.3 @@ -43,7 +43,7 @@ install: all
    29.4  
    29.5  .PHONY: clean
    29.6  clean:
    29.7 -	rm -rf *.a *.so* *.o *.rpm $(LIB) *~ $(DEPS) xen TAGS
    29.8 +	rm -rf *.a *.so* *.o *.opic *.rpm $(LIB) *~ $(DEPS) xen TAGS
    29.9  
   29.10  libblktap.so.$(MAJOR).$(MINOR): $(OBJS_PIC) 
   29.11  	$(CC) $(CFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,$(SONAME) $(SHLIB_CFLAGS) \
    30.1 --- a/tools/console/Makefile	Thu Aug 07 11:47:34 2008 +0900
    30.2 +++ b/tools/console/Makefile	Thu Aug 07 11:57:34 2008 +0900
    30.3 @@ -21,7 +21,7 @@ clean:
    30.4  
    30.5  xenconsoled: $(patsubst %.c,%.o,$(wildcard daemon/*.c))
    30.6  	$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) \
    30.7 -              $(UTIL_LIBS) $(SOCKET_LIBS)
    30.8 +              $(UTIL_LIBS) $(SOCKET_LIBS) -lrt
    30.9  
   30.10  xenconsole: $(patsubst %.c,%.o,$(wildcard client/*.c))
   30.11  	$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) \
    31.1 --- a/tools/console/daemon/io.c	Thu Aug 07 11:47:34 2008 +0900
    31.2 +++ b/tools/console/daemon/io.c	Thu Aug 07 11:57:34 2008 +0900
    31.3 @@ -622,9 +622,9 @@ static struct domain *create_domain(int 
    31.4  {
    31.5  	struct domain *dom;
    31.6  	char *s;
    31.7 -	struct timeval tv;
    31.8 +	struct timespec ts;
    31.9  
   31.10 -	if (gettimeofday(&tv, NULL) < 0) {
   31.11 +	if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) {
   31.12  		dolog(LOG_ERR, "Cannot get time of day %s:%s:L%d",
   31.13  		      __FILE__, __FUNCTION__, __LINE__);
   31.14  		return NULL;
   31.15 @@ -666,7 +666,7 @@ static struct domain *create_domain(int 
   31.16  	dom->buffer.capacity = 0;
   31.17  	dom->buffer.max_capacity = 0;
   31.18  	dom->event_count = 0;
   31.19 -	dom->next_period = (tv.tv_sec * 1000) + (tv.tv_usec / 1000) + RATE_LIMIT_PERIOD;
   31.20 +	dom->next_period = (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000) + RATE_LIMIT_PERIOD;
   31.21  	dom->next = NULL;
   31.22  
   31.23  	dom->ring_ref = -1;
   31.24 @@ -971,7 +971,7 @@ void handle_io(void)
   31.25  		struct domain *d, *n;
   31.26  		int max_fd = -1;
   31.27  		struct timeval timeout;
   31.28 -		struct timeval tv;
   31.29 +		struct timespec ts;
   31.30  		long long now, next_timeout = 0;
   31.31  
   31.32  		FD_ZERO(&readfds);
   31.33 @@ -985,9 +985,9 @@ void handle_io(void)
   31.34  			max_fd = MAX(xc_evtchn_fd(xce_handle), max_fd);
   31.35  		}
   31.36  
   31.37 -		if (gettimeofday(&tv, NULL) < 0)
   31.38 +		if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0)
   31.39  			return;
   31.40 -		now = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
   31.41 +		now = (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000);
   31.42  
   31.43  		/* Re-calculate any event counter allowances & unblock
   31.44  		   domains with new allowance */
    32.1 --- a/tools/examples/Makefile	Thu Aug 07 11:47:34 2008 +0900
    32.2 +++ b/tools/examples/Makefile	Thu Aug 07 11:57:34 2008 +0900
    32.3 @@ -8,11 +8,18 @@ XENDOMAINS_SYSCONFIG = init.d/sysconfig.
    32.4  
    32.5  # Xen configuration dir and configs to go there.
    32.6  XEN_CONFIG_DIR = /etc/xen
    32.7 +XEN_READMES = README
    32.8 +XEN_READMES += README.incompatibilities
    32.9  XEN_CONFIGS = xend-config.sxp
   32.10  XEN_CONFIGS += xm-config.xml
   32.11  XEN_CONFIGS += xmexample1 
   32.12  XEN_CONFIGS += xmexample2
   32.13 +XEN_CONFIGS += xmexample3
   32.14  XEN_CONFIGS += xmexample.hvm
   32.15 +XEN_CONFIGS += xmexample.hvm-stubdom
   32.16 +XEN_CONFIGS += xmexample.hvm-dm
   32.17 +XEN_CONFIGS += xmexample.pv-grub
   32.18 +XEN_CONFIGS += xmexample.nbd
   32.19  XEN_CONFIGS += xmexample.vti
   32.20  XEN_CONFIGS += xend-pci-quirks.sxp
   32.21  XEN_CONFIGS += xend-pci-permissive.sxp
   32.22 @@ -59,7 +66,16 @@ all:
   32.23  build:
   32.24  
   32.25  .PHONY: install
   32.26 -install: all install-initd install-configs install-scripts $(HOTPLUGS)
   32.27 +install: all install-readmes install-initd install-configs install-scripts $(HOTPLUGS)
   32.28 +
   32.29 +.PHONY: install-readmes
   32.30 +install-readmes:
   32.31 +	[ -d $(DESTDIR)$(XEN_CONFIG_DIR) ] || \
   32.32 +		$(INSTALL_DIR) $(DESTDIR)$(XEN_CONFIG_DIR)
   32.33 +	set -e; for i in $(XEN_READMES); \
   32.34 +	    do [ -e $(DESTDIR)$(XEN_CONFIG_DIR)/$$i ] || \
   32.35 +	    $(INSTALL_DATA) $$i $(DESTDIR)$(XEN_CONFIG_DIR); \
   32.36 +	done
   32.37  
   32.38  .PHONY: install-initd
   32.39  install-initd:
    33.1 --- a/tools/examples/README	Thu Aug 07 11:47:34 2008 +0900
    33.2 +++ b/tools/examples/README	Thu Aug 07 11:57:34 2008 +0900
    33.3 @@ -44,4 +44,8 @@ xmexample3          - an advanced config
    33.4  xmexample.nbd       - configuration script that uses NBD filesystems
    33.5  xmexample.hvm       - a configuration script for creating a hvm domain with
    33.6                        'xm create'
    33.7 +xmexample.hvm-stubdom - a configuration script for creating a hvm domain with
    33.8 +                        'xm create' that utilizes a stubdomain for device model
    33.9 +xmexample.pv-grub   - a configuration script for creating a domain with 'xm create'
   33.10 +                      which boots PV-GRUB.
   33.11  xmexample.vti       - a configuration script for creating a domain on vti
    34.1 --- a/tools/examples/stubdom-ExampleHVMDomain	Thu Aug 07 11:47:34 2008 +0900
    34.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.3 @@ -1,14 +0,0 @@
    34.4 -# Not to be started directly,
    34.5 -# See xmexample.hvm-stubdom and stubdom/README for more details
    34.6 -
    34.7 -kernel = "/usr/lib/xen/boot/ioemu-stubdom.gz"
    34.8 -
    34.9 -# Must be the same as in xmexample.hvm-stubdom, with a prepended vif for TCP/IP
   34.10 -# networking in the stubdomain itself, here just ''
   34.11 -vif = [ '', 'type=ioemu, bridge=xenbr0' ]
   34.12 -
   34.13 -# Set here instead of in xmexample.hvm-stubdom
   34.14 -disk = [ 'file:/var/images/min-el3-i386.img,hda,w', ',hdc:cdrom,r' ]
   34.15 -
   34.16 -# Actual output via PVFB
   34.17 -vfb = [ 'type=sdl' ]
    35.1 --- a/tools/examples/xend-config.sxp	Thu Aug 07 11:47:34 2008 +0900
    35.2 +++ b/tools/examples/xend-config.sxp	Thu Aug 07 11:57:34 2008 +0900
    35.3 @@ -245,3 +245,7 @@
    35.4  
    35.5  # Rotation count of qemu-dm log file.
    35.6  #(qemu-dm-logrotate-count 10)
    35.7 +
    35.8 +# Path where persistent domain configuration is stored.
    35.9 +# Default is /var/lib/xend/domains/
   35.10 +#(xend-domains-path /var/lib/xend/domains)
    36.1 --- a/tools/examples/xmexample.hvm	Thu Aug 07 11:47:34 2008 +0900
    36.2 +++ b/tools/examples/xmexample.hvm	Thu Aug 07 11:57:34 2008 +0900
    36.3 @@ -158,11 +158,6 @@ vnc=1
    36.4  #vncunused=1
    36.5  
    36.6  #----------------------------------------------------------------------------
    36.7 -# enable spawning vncviewer for domain's console
    36.8 -# (only valid when vnc=1), default = 0
    36.9 -#vncconsole=0
   36.10 -
   36.11 -#----------------------------------------------------------------------------
   36.12  # set password for domain's VNC console
   36.13  # default is depents on vncpasswd in xend-config.sxp
   36.14  vncpasswd=''
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/tools/examples/xmexample.hvm-dm	Thu Aug 07 11:57:34 2008 +0900
    37.3 @@ -0,0 +1,14 @@
    37.4 +# Not to be started directly,
    37.5 +# See xmexample.hvm-stubdom and stubdom/README for more details
    37.6 +
    37.7 +kernel = "/usr/lib/xen/boot/ioemu-stubdom.gz"
    37.8 +
    37.9 +# Must be the same as in xmexample.hvm-stubdom, with a prepended vif for TCP/IP
   37.10 +# networking in the stubdomain itself, here just ''
   37.11 +vif = [ '', 'type=ioemu, bridge=xenbr0' ]
   37.12 +
   37.13 +# Set here instead of in xmexample.hvm-stubdom
   37.14 +disk = [ 'file:/var/images/min-el3-i386.img,hda,w', ',hdc:cdrom,r' ]
   37.15 +
   37.16 +# Actual output via PVFB
   37.17 +vfb = [ 'type=sdl' ]
    38.1 --- a/tools/examples/xmexample.hvm-stubdom	Thu Aug 07 11:47:34 2008 +0900
    38.2 +++ b/tools/examples/xmexample.hvm-stubdom	Thu Aug 07 11:57:34 2008 +0900
    38.3 @@ -7,7 +7,7 @@
    38.4  #============================================================================
    38.5  #
    38.6  # This is a version using a stubdomain for device model, see
    38.7 -# stubdom-ExampleHVMDomain and stubdom/README for more details
    38.8 +# xmexample.hvm-dm and README.stubdom for more details
    38.9  # The differences with xmexample.hvm are marked with "STUBDOM"
   38.10  
   38.11  #----------------------------------------------------------------------------
   38.12 @@ -30,7 +30,7 @@ memory = 128
   38.13  # shadow_memory = 8
   38.14  
   38.15  # A name for your domain. All domains must have different names.
   38.16 -name = "ExampleHVMDomain"
   38.17 +name = "xmexample.hvm"
   38.18  
   38.19  # 128-bit UUID for the domain.  The default behavior is to generate a new UUID
   38.20  # on each call to 'xm create'.
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/tools/examples/xmexample.pv-grub	Thu Aug 07 11:57:34 2008 +0900
    39.3 @@ -0,0 +1,212 @@
    39.4 +#  -*- mode: python; -*-
    39.5 +#============================================================================
    39.6 +# Python configuration setup for 'xm create'.
    39.7 +# This script sets the parameters used when a domain is created using 'xm create'.
    39.8 +# You use a separate script for each domain you want to create, or 
    39.9 +# you can set the parameters for the domain on the xm command line.
   39.10 +#============================================================================
   39.11 +
   39.12 +#----------------------------------------------------------------------------
   39.13 +# PV GRUB image file.
   39.14 +kernel = "/usr/lib/xen/boot/pv-grub.gz"
   39.15 +
   39.16 +# Optional provided menu.lst.
   39.17 +#ramdisk = "/boot/guests/menu.lst"
   39.18 +
   39.19 +# Sets path to menu.lst
   39.20 +extra = "(hd0,0)/boot/grub/menu.lst"
   39.21 +# can be a TFTP-served path (DHCP will automatically be run)
   39.22 +# extra = "(nd)/netboot/menu.lst"
   39.23 +# can be configured automatically by GRUB's DHCP option 150 (see grub manual)
   39.24 +# extra = ""
   39.25 +
   39.26 +# Initial memory allocation (in megabytes) for the new domain.
   39.27 +#
   39.28 +# WARNING: Creating a domain with insufficient memory may cause out of
   39.29 +#          memory errors. The domain needs enough memory to boot kernel
   39.30 +#          and modules. Allocating less than 32MBs is not recommended.
   39.31 +memory = 64
   39.32 +
   39.33 +# A name for your domain. All domains must have different names.
   39.34 +name = "ExampleDomain"
   39.35 +
   39.36 +# 128-bit UUID for the domain.  The default behavior is to generate a new UUID
   39.37 +# on each call to 'xm create'.
   39.38 +#uuid = "06ed00fe-1162-4fc4-b5d8-11993ee4a8b9"
   39.39 +
   39.40 +# List of which CPUS this domain is allowed to use, default Xen picks
   39.41 +#cpus = ""         # leave to Xen to pick
   39.42 +#cpus = "0"        # all vcpus run on CPU0
   39.43 +#cpus = "0-3,5,^1" # all vcpus run on cpus 0,2,3,5
   39.44 +#cpus = ["2", "3"] # VCPU0 runs on CPU2, VCPU1 runs on CPU3
   39.45 +
   39.46 +# Number of Virtual CPUS to use, default is 1
   39.47 +#vcpus = 1
   39.48 +
   39.49 +#----------------------------------------------------------------------------
   39.50 +# Define network interfaces.
   39.51 +
   39.52 +# By default, no network interfaces are configured.  You may have one created
   39.53 +# with sensible defaults using an empty vif clause:
   39.54 +#
   39.55 +# vif = [ '' ]
   39.56 +#
   39.57 +# or optionally override backend, bridge, ip, mac, script, type, or vifname:
   39.58 +#
   39.59 +# vif = [ 'mac=00:16:3e:00:00:11, bridge=xenbr0' ]
   39.60 +#
   39.61 +# or more than one interface may be configured:
   39.62 +#
   39.63 +# vif = [ '', 'bridge=xenbr1' ]
   39.64 +
   39.65 +vif = [ '' ]
   39.66 +
   39.67 +#----------------------------------------------------------------------------
   39.68 +# Define the disk devices you want the domain to have access to, and
   39.69 +# what you want them accessible as.
   39.70 +# Each disk entry is of the form phy:UNAME,DEV,MODE
   39.71 +# where UNAME is the device, DEV is the device name the domain will see,
   39.72 +# and MODE is r for read-only, w for read-write.
   39.73 +
   39.74 +disk = [ 'phy:hda1,hda1,w' ]
   39.75 +
   39.76 +#----------------------------------------------------------------------------
   39.77 +# Define frame buffer device.
   39.78 +#
   39.79 +# By default, no frame buffer device is configured.
   39.80 +#
   39.81 +# To create one using the SDL backend and sensible defaults:
   39.82 +#
   39.83 +# vfb = [ 'type=sdl' ]
   39.84 +#
   39.85 +# This uses environment variables XAUTHORITY and DISPLAY.  You
   39.86 +# can override that:
   39.87 +#
   39.88 +# vfb = [ 'type=sdl,xauthority=/home/bozo/.Xauthority,display=:1' ]
   39.89 +#
   39.90 +# To create one using the VNC backend and sensible defaults:
   39.91 +#
   39.92 +# vfb = [ 'type=vnc' ]
   39.93 +#
   39.94 +# The backend listens on 127.0.0.1 port 5900+N by default, where N is
   39.95 +# the domain ID.  You can override both address and N:
   39.96 +#
   39.97 +# vfb = [ 'type=vnc,vnclisten=127.0.0.1,vncdisplay=1' ]
   39.98 +#
   39.99 +# Or you can bind the first unused port above 5900:
  39.100 +#
  39.101 +# vfb = [ 'type=vnc,vnclisten=0.0.0.0,vncunused=1' ]
  39.102 +#
  39.103 +# You can override the password:
  39.104 +#
  39.105 +# vfb = [ 'type=vnc,vncpasswd=MYPASSWD' ]
  39.106 +#
  39.107 +# Empty password disables authentication.  Defaults to the vncpasswd
  39.108 +# configured in xend-config.sxp.
  39.109 +
  39.110 +#----------------------------------------------------------------------------
  39.111 +# Define to which TPM instance the user domain should communicate.
  39.112 +# The vtpm entry is of the form 'instance=INSTANCE,backend=DOM'
  39.113 +# where INSTANCE indicates the instance number of the TPM the VM
  39.114 +# should be talking to and DOM provides the domain where the backend
  39.115 +# is located.
  39.116 +# Note that no two virtual machines should try to connect to the same
  39.117 +# TPM instance. The handling of all TPM instances does require
  39.118 +# some management effort in so far that VM configration files (and thus
  39.119 +# a VM) should be associated with a TPM instance throughout the lifetime
  39.120 +# of the VM / VM configuration file. The instance number must be
  39.121 +# greater or equal to 1.
  39.122 +#vtpm = [ 'instance=1,backend=0' ]
  39.123 +
  39.124 +#----------------------------------------------------------------------------
  39.125 +# Set the kernel command line for the new domain.
  39.126 +# You only need to define the IP parameters and hostname if the domain's
  39.127 +# IP config doesn't, e.g. in ifcfg-eth0 or via DHCP.
  39.128 +# You can use 'extra' to set the runlevel and custom environment
  39.129 +# variables used by custom rc scripts (e.g. VMID=, usr= ).
  39.130 +
  39.131 +# Set if you want dhcp to allocate the IP address.
  39.132 +#dhcp="dhcp"
  39.133 +# Set netmask.
  39.134 +#netmask=
  39.135 +# Set default gateway.
  39.136 +#gateway=
  39.137 +# Set the hostname.
  39.138 +#hostname= "vm%d" % vmid
  39.139 +
  39.140 +# Set root device.
  39.141 +root = "/dev/hda1 ro"
  39.142 +
  39.143 +# Root device for nfs.
  39.144 +#root = "/dev/nfs"
  39.145 +# The nfs server.
  39.146 +#nfs_server = '192.0.2.1'  
  39.147 +# Root directory on the nfs server.
  39.148 +#nfs_root   = '/full/path/to/root/directory'
  39.149 +
  39.150 +#----------------------------------------------------------------------------
  39.151 +# Configure the behaviour when a domain exits.  There are three 'reasons'
  39.152 +# for a domain to stop: poweroff, reboot, and crash.  For each of these you
  39.153 +# may specify:
  39.154 +#
  39.155 +#   "destroy",        meaning that the domain is cleaned up as normal;
  39.156 +#   "restart",        meaning that a new domain is started in place of the old
  39.157 +#                     one;
  39.158 +#   "preserve",       meaning that no clean-up is done until the domain is
  39.159 +#                     manually destroyed (using xm destroy, for example); or
  39.160 +#   "rename-restart", meaning that the old domain is not cleaned up, but is
  39.161 +#                     renamed and a new domain started in its place.
  39.162 +#
  39.163 +# In the event a domain stops due to a crash, you have the additional options:
  39.164 +#
  39.165 +#   "coredump-destroy", meaning dump the crashed domain's core and then destroy;
  39.166 +#   "coredump-restart', meaning dump the crashed domain's core and the restart.
  39.167 +#
  39.168 +# The default is
  39.169 +#
  39.170 +#   on_poweroff = 'destroy'
  39.171 +#   on_reboot   = 'restart'
  39.172 +#   on_crash    = 'restart'
  39.173 +#
  39.174 +# For backwards compatibility we also support the deprecated option restart
  39.175 +#
  39.176 +# restart = 'onreboot' means on_poweroff = 'destroy'
  39.177 +#                            on_reboot   = 'restart'
  39.178 +#                            on_crash    = 'destroy'
  39.179 +#
  39.180 +# restart = 'always'   means on_poweroff = 'restart'
  39.181 +#                            on_reboot   = 'restart'
  39.182 +#                            on_crash    = 'restart'
  39.183 +#
  39.184 +# restart = 'never'    means on_poweroff = 'destroy'
  39.185 +#                            on_reboot   = 'destroy'
  39.186 +#                            on_crash    = 'destroy'
  39.187 +
  39.188 +#on_poweroff = 'destroy'
  39.189 +#on_reboot   = 'restart'
  39.190 +#on_crash    = 'restart'
  39.191 +
  39.192 +#-----------------------------------------------------------------------------
  39.193 +#   Configure PVSCSI devices:
  39.194 +#
  39.195 +#vscsi=[ 'PDEV, VDEV' ]
  39.196 +#
  39.197 +#   PDEV   gives physical SCSI device to be attached to specified guest
  39.198 +#          domain by one of the following identifier format.
  39.199 +#          - XX:XX:XX:XX (4-tuples with decimal notation which shows
  39.200 +#                          "host:channel:target:lun")
  39.201 +#          - /dev/sdxx or sdx
  39.202 +#          - /dev/stxx or stx
  39.203 +#          - /dev/sgxx or sgx
  39.204 +#          - result of 'scsi_id -gu -s'.
  39.205 +#            ex. # scsi_id -gu -s /block/sdb
  39.206 +#                  36000b5d0006a0000006a0257004c0000
  39.207 +#
  39.208 +#   VDEV   gives virtual SCSI device by 4-tuples (XX:XX:XX:XX) as 
  39.209 +#          which the specified guest domain recognize.
  39.210 +#
  39.211 +
  39.212 +#vscsi = [ '/dev/sdx, 0:0:0:0' ]
  39.213 +
  39.214 +#============================================================================
  39.215 +
    40.1 --- a/tools/examples/xmexample.vti	Thu Aug 07 11:47:34 2008 +0900
    40.2 +++ b/tools/examples/xmexample.vti	Thu Aug 07 11:57:34 2008 +0900
    40.3 @@ -95,11 +95,6 @@ vnc=0
    40.4  #vncunused=1
    40.5  
    40.6  #----------------------------------------------------------------------------
    40.7 -# enable spawning vncviewer for domain's console
    40.8 -# (only valid when vnc=1), default = 0
    40.9 -#vncconsole=0
   40.10 -
   40.11 -#----------------------------------------------------------------------------
   40.12  # set password for domain's VNC console
   40.13  # default is depents on vncpasswd in xend-config.sxp
   40.14  vncpasswd=''
    41.1 --- a/tools/examples/xmexample3	Thu Aug 07 11:47:34 2008 +0900
    41.2 +++ b/tools/examples/xmexample3	Thu Aug 07 11:57:34 2008 +0900
    41.3 @@ -207,4 +207,26 @@ extra = "4 VMID=%d" % vmid
    41.4  #on_reboot   = 'restart'
    41.5  #on_crash    = 'restart'
    41.6  
    41.7 +#-----------------------------------------------------------------------------
    41.8 +#   Configure PVSCSI devices:
    41.9 +#
   41.10 +#vscsi=[ 'PDEV, VDEV' ]
   41.11 +#
   41.12 +#   PDEV   gives physical SCSI device to be attached to specified guest
   41.13 +#          domain by one of the following identifier format.
   41.14 +#          - XX:XX:XX:XX (4-tuples with decimal notation which shows
   41.15 +#                          "host:channel:target:lun")
   41.16 +#          - /dev/sdxx or sdx
   41.17 +#          - /dev/stxx or stx
   41.18 +#          - /dev/sgxx or sgx
   41.19 +#          - result of 'scsi_id -gu -s'.
   41.20 +#            ex. # scsi_id -gu -s /block/sdb
   41.21 +#                  36000b5d0006a0000006a0257004c0000
   41.22 +#
   41.23 +#   VDEV   gives virtual SCSI device by 4-tuples (XX:XX:XX:XX) as 
   41.24 +#          which the specified guest domain recognize.
   41.25 +#
   41.26 +
   41.27 +#vscsi = [ '/dev/sdx, 0:0:0:0' ]
   41.28 +
   41.29  #============================================================================
    42.1 --- a/tools/firmware/extboot/Makefile	Thu Aug 07 11:47:34 2008 +0900
    42.2 +++ b/tools/firmware/extboot/Makefile	Thu Aug 07 11:57:34 2008 +0900
    42.3 @@ -1,8 +1,6 @@
    42.4  XEN_ROOT = ../../..
    42.5  include $(XEN_ROOT)/tools/firmware/Rules.mk
    42.6  
    42.7 -CFLAGS += -I$(XEN_ROOT)/tools/libxc -I.
    42.8 -
    42.9  .PHONY: all
   42.10  all: extboot.bin
   42.11  
    43.1 --- a/tools/firmware/hvmloader/Makefile	Thu Aug 07 11:47:34 2008 +0900
    43.2 +++ b/tools/firmware/hvmloader/Makefile	Thu Aug 07 11:57:34 2008 +0900
    43.3 @@ -33,14 +33,14 @@ SRCS += 32bitbios_support.c smp.c cachea
    43.4  OBJS  = $(patsubst %.c,%.o,$(SRCS))
    43.5  
    43.6  .PHONY: all
    43.7 -all: hvmloader
    43.8 +all: subdirs-all
    43.9 +	$(MAKE) hvmloader
   43.10  
   43.11  hvmloader.o: roms.h
   43.12  smbios.o: CFLAGS += -D__SMBIOS_DATE__="\"$(shell date +%m/%d/%Y)\""
   43.13  
   43.14 -hvmloader: subdirs-all $(OBJS)
   43.15 -	$(LD) $(LDFLAGS_DIRECT) -N -Ttext $(LOADADDR) \
   43.16 -		-o hvmloader.tmp $(OBJS) acpi/acpi.a
   43.17 +hvmloader: $(OBJS) acpi/acpi.a
   43.18 +	$(LD) $(LDFLAGS_DIRECT) -N -Ttext $(LOADADDR) -o hvmloader.tmp $^
   43.19  	$(OBJCOPY) hvmloader.tmp hvmloader
   43.20  	rm -f hvmloader.tmp
   43.21  
    44.1 --- a/tools/firmware/hvmloader/acpi/acpi2_0.h	Thu Aug 07 11:47:34 2008 +0900
    44.2 +++ b/tools/firmware/hvmloader/acpi/acpi2_0.h	Thu Aug 07 11:57:34 2008 +0900
    44.3 @@ -381,7 +381,7 @@ struct acpi_20_madt_intsrcovr {
    44.4  
    44.5  #pragma pack ()
    44.6  
    44.7 -int acpi_build_tables(uint8_t *);
    44.8 +void acpi_build_tables(void);
    44.9  
   44.10  #endif /* _ACPI_2_0_H_ */
   44.11  
    45.1 --- a/tools/firmware/hvmloader/acpi/build.c	Thu Aug 07 11:47:34 2008 +0900
    45.2 +++ b/tools/firmware/hvmloader/acpi/build.c	Thu Aug 07 11:57:34 2008 +0900
    45.3 @@ -248,8 +248,7 @@ static int construct_secondary_tables(ui
    45.4      return align16(offset);
    45.5  }
    45.6  
    45.7 -/* Copy all the ACPI table to buffer. */
    45.8 -int acpi_build_tables(uint8_t *buf)
    45.9 +static void __acpi_build_tables(uint8_t *buf, int *low_sz, int *high_sz)
   45.10  {
   45.11      struct acpi_20_rsdp *rsdp;
   45.12      struct acpi_20_rsdt *rsdt;
   45.13 @@ -261,7 +260,9 @@ int acpi_build_tables(uint8_t *buf)
   45.14      unsigned long        secondary_tables[16];
   45.15      int                  offset = 0, i;
   45.16  
   45.17 -    offset += construct_bios_info_table(&buf[offset]);
   45.18 +    /*
   45.19 +     * Fill in high-memory data structures, starting at @buf.
   45.20 +     */
   45.21  
   45.22      facs = (struct acpi_20_facs *)&buf[offset];
   45.23      memcpy(facs, &Facs, sizeof(struct acpi_20_facs));
   45.24 @@ -325,7 +326,18 @@ int acpi_build_tables(uint8_t *buf)
   45.25                   offsetof(struct acpi_header, checksum),
   45.26                   rsdt->header.length);
   45.27  
   45.28 +    *high_sz = offset;
   45.29 +
   45.30 +    /*
   45.31 +     * Fill in low-memory data structures: bios_info_table and RSDP.
   45.32 +     */
   45.33 +
   45.34 +    buf = (uint8_t *)ACPI_PHYSICAL_ADDRESS;
   45.35 +    offset = 0;
   45.36 +
   45.37 +    offset += construct_bios_info_table(&buf[offset]);
   45.38      rsdp = (struct acpi_20_rsdp *)&buf[offset];
   45.39 +
   45.40      memcpy(rsdp, &Rsdp, sizeof(struct acpi_20_rsdp));
   45.41      offset += align16(sizeof(struct acpi_20_rsdp));
   45.42      rsdp->rsdt_address = (unsigned long)rsdt;
   45.43 @@ -337,7 +349,28 @@ int acpi_build_tables(uint8_t *buf)
   45.44                   offsetof(struct acpi_20_rsdp, extended_checksum),
   45.45                   sizeof(struct acpi_20_rsdp));
   45.46  
   45.47 -    return offset;
   45.48 +    *low_sz = offset;
   45.49 +}
   45.50 +
   45.51 +void acpi_build_tables(void)
   45.52 +{
   45.53 +    int high_sz, low_sz;
   45.54 +    uint8_t *buf;
   45.55 +
   45.56 +    /* Find out size of high-memory ACPI data area. */
   45.57 +    buf = (uint8_t *)&_end;
   45.58 +    __acpi_build_tables(buf, &low_sz, &high_sz);
   45.59 +    memset(buf, 0, high_sz);
   45.60 +
   45.61 +    /* Allocate data area and set up ACPI tables there. */
   45.62 +    buf = (uint8_t *)e820_malloc(high_sz);
   45.63 +    __acpi_build_tables(buf, &low_sz, &high_sz);
   45.64 +
   45.65 +    printf(" - Lo data: %08lx-%08lx\n"
   45.66 +           " - Hi data: %08lx-%08lx\n",
   45.67 +           (unsigned long)ACPI_PHYSICAL_ADDRESS,
   45.68 +           (unsigned long)ACPI_PHYSICAL_ADDRESS + low_sz - 1,
   45.69 +           (unsigned long)buf, (unsigned long)buf + high_sz - 1);
   45.70  }
   45.71  
   45.72  /*
    46.1 --- a/tools/firmware/hvmloader/hvmloader.c	Thu Aug 07 11:47:34 2008 +0900
    46.2 +++ b/tools/firmware/hvmloader/hvmloader.c	Thu Aug 07 11:57:34 2008 +0900
    46.3 @@ -449,7 +449,7 @@ static void init_xen_platform_io_base(vo
    46.4  
    46.5  int main(void)
    46.6  {
    46.7 -    int acpi_sz = 0, vgabios_sz = 0, etherboot_sz = 0, rombios_sz, smbios_sz;
    46.8 +    int vgabios_sz = 0, etherboot_sz = 0, rombios_sz, smbios_sz;
    46.9      int extboot_sz = 0;
   46.10  
   46.11      printf("HVM Loader\n");
   46.12 @@ -508,8 +508,7 @@ int main(void)
   46.13      if ( get_acpi_enabled() )
   46.14      {
   46.15          printf("Loading ACPI ...\n");
   46.16 -        acpi_sz = acpi_build_tables((uint8_t *)ACPI_PHYSICAL_ADDRESS);
   46.17 -        ASSERT((ACPI_PHYSICAL_ADDRESS + acpi_sz) <= 0xF0000);
   46.18 +        acpi_build_tables();
   46.19      }
   46.20  
   46.21      cmos_write_memory_size();
   46.22 @@ -531,10 +530,6 @@ int main(void)
   46.23          printf(" %05x-%05x: SMBIOS tables\n",
   46.24                 SMBIOS_PHYSICAL_ADDRESS,
   46.25                 SMBIOS_PHYSICAL_ADDRESS + smbios_sz - 1);
   46.26 -    if ( acpi_sz )
   46.27 -        printf(" %05x-%05x: ACPI tables\n",
   46.28 -               ACPI_PHYSICAL_ADDRESS,
   46.29 -               ACPI_PHYSICAL_ADDRESS + acpi_sz - 1);
   46.30      if ( rombios_sz )
   46.31          printf(" %05x-%05x: Main BIOS\n",
   46.32                 ROMBIOS_PHYSICAL_ADDRESS,
    47.1 --- a/tools/firmware/hvmloader/util.h	Thu Aug 07 11:47:34 2008 +0900
    47.2 +++ b/tools/firmware/hvmloader/util.h	Thu Aug 07 11:57:34 2008 +0900
    47.3 @@ -145,4 +145,6 @@ void smp_initialise(void);
    47.4  
    47.5  #define isdigit(c) ((c) >= '0' && (c) <= '9')
    47.6  
    47.7 +extern char _start[], _end[];
    47.8 +
    47.9  #endif /* __HVMLOADER_UTIL_H__ */
    48.1 --- a/tools/firmware/rombios/32bit/32bitbios.c	Thu Aug 07 11:47:34 2008 +0900
    48.2 +++ b/tools/firmware/rombios/32bit/32bitbios.c	Thu Aug 07 11:57:34 2008 +0900
    48.3 @@ -47,5 +47,7 @@ uint32_t jumptable[IDX_LAST+1] __attribu
    48.4  
    48.5  	TABLE_ENTRY(IDX_TCPA_INITIALIZE_TPM, tcpa_initialize_tpm),
    48.6  
    48.7 +	TABLE_ENTRY(IDX_GET_S3_WAKING_VECTOR, get_s3_waking_vector),
    48.8 +
    48.9  	TABLE_ENTRY(IDX_LAST       , 0)     /* keep last */
   48.10  };
    49.1 --- a/tools/firmware/rombios/32bit/Makefile	Thu Aug 07 11:47:34 2008 +0900
    49.2 +++ b/tools/firmware/rombios/32bit/Makefile	Thu Aug 07 11:57:34 2008 +0900
    49.3 @@ -4,21 +4,22 @@ include $(XEN_ROOT)/tools/firmware/Rules
    49.4  SOURCES = util.c
    49.5  TARGET = 32bitbios_flat.h
    49.6  
    49.7 -CFLAGS += -I../ -DGCC_PROTOS
    49.8 +CFLAGS += $(CFLAGS_include) -I.. -DGCC_PROTOS
    49.9  
   49.10  SUBDIRS = tcgbios
   49.11  
   49.12  MODULES = tcgbios/tcgbiosext.o
   49.13  
   49.14  .PHONY: all
   49.15 -all: $(TARGET)
   49.16 +all: subdirs-all
   49.17 +	$(MAKE) $(TARGET)
   49.18  
   49.19  .PHONY: clean
   49.20  clean: subdirs-clean
   49.21  	rm -rf *.o $(TARGET)
   49.22  
   49.23 -$(TARGET): subdirs-all 32bitbios.o util.o
   49.24 -	$(LD) $(LDFLAGS_DIRECT) -s -r 32bitbios.o $(MODULES) util.o -o 32bitbios_all.o
   49.25 +$(TARGET): 32bitbios.o $(MODULES) util.o
   49.26 +	$(LD) $(LDFLAGS_DIRECT) -s -r $^ -o 32bitbios_all.o
   49.27  	@nm 32bitbios_all.o |                                \
   49.28  	  egrep '^ +U ' >/dev/null && {                      \
   49.29  	    echo "There are undefined symbols in the BIOS:"; \
    50.1 --- a/tools/firmware/rombios/32bit/tcgbios/Makefile	Thu Aug 07 11:47:34 2008 +0900
    50.2 +++ b/tools/firmware/rombios/32bit/tcgbios/Makefile	Thu Aug 07 11:57:34 2008 +0900
    50.3 @@ -5,7 +5,7 @@ TARGET  = tcgbiosext.o
    50.4  FILES   = tcgbios tpm_drivers
    50.5  OBJECTS = $(foreach f,$(FILES),$(f).o)
    50.6  
    50.7 -CFLAGS += -I../ -I../../ -DGCC_PROTOS
    50.8 +CFLAGS += $(CFLAGS_include) -I.. -I../.. -DGCC_PROTOS
    50.9  
   50.10  .PHONY: all clean
   50.11  
    51.1 --- a/tools/firmware/rombios/32bit/tcgbios/tcgbios.c	Thu Aug 07 11:47:34 2008 +0900
    51.2 +++ b/tools/firmware/rombios/32bit/tcgbios/tcgbios.c	Thu Aug 07 11:57:34 2008 +0900
    51.3 @@ -24,10 +24,9 @@
    51.4  #include "rombios_compat.h"
    51.5  #include "tpm_drivers.h"
    51.6  
    51.7 +#include "util.h"
    51.8  #include "tcgbios.h"
    51.9  #include "32bitprotos.h"
   51.10 -#include "util.h"
   51.11 -
   51.12  
   51.13  /* local structure and variables */
   51.14  struct ptti_cust {
   51.15 @@ -135,7 +134,7 @@ static inline uint32_t bswap(uint32_t a)
   51.16   *******************************************************/
   51.17  
   51.18  typedef struct {
   51.19 -	struct acpi_20_tcpa *tcpa_ptr;
   51.20 +	struct acpi_20_tcpa_clisrv *tcpa_ptr;
   51.21  	unsigned char       *lasa_last_ptr;
   51.22  	uint16_t            entry_count;
   51.23  	uint16_t            flags;
   51.24 @@ -260,45 +259,19 @@ uint8_t acpi_validate_entry(struct acpi_
   51.25  }
   51.26  
   51.27  
   51.28 -/*
   51.29 - * Search for the RSDP ACPI table in the memory starting at addr and
   51.30 - * ending at addr + len - 1.
   51.31 - */
   51.32 -static struct acpi_20_rsdp *find_rsdp(const void *start, unsigned int len)
   51.33 -{
   51.34 -	char *rsdp = (char *)start;
   51.35 -	char *end = rsdp + len;
   51.36 -	/* scan memory in steps of 16 bytes */
   51.37 -	while (rsdp < end) {
   51.38 -		/* check for expected string */
   51.39 -		if (!strncmp( rsdp, "RSD PTR ", 8))
   51.40 -			return (struct acpi_20_rsdp *)rsdp;
   51.41 -		rsdp += 0x10;
   51.42 -	}
   51.43 -	return 0;
   51.44 -}
   51.45 -
   51.46  void tcpa_acpi_init(void)
   51.47  {
   51.48  	struct acpi_20_rsdt *rsdt;
   51.49 -	struct acpi_20_tcpa *tcpa = (void *)0;
   51.50 +	struct acpi_20_tcpa_clisrv *tcpa = (void *)0;
   51.51  	struct acpi_20_rsdp *rsdp;
   51.52  	uint32_t length;
   51.53  	uint16_t off;
   51.54  	int found = 0;
   51.55 -	uint16_t ebda_seg;
   51.56 -
   51.57 -	if (MA_IsTPMPresent() == 0) {
   51.58 -		return;
   51.59 -	}
   51.60  
   51.61 -	/* RSDP in EBDA? */
   51.62 -	ebda_seg = *(uint16_t *)ADDR_FROM_SEG_OFF(0x40, 0xe);
   51.63 -	rsdp = find_rsdp((void *)(ebda_seg << 16), 1024);
   51.64 +	if (MA_IsTPMPresent() == 0)
   51.65 +		return;
   51.66  
   51.67 -	if (!rsdp)
   51.68 -		rsdp = find_rsdp((void *)(ACPI_SEGMENT << 4), 0x20000);
   51.69 -
   51.70 +	rsdp = find_rsdp();
   51.71  	if (rsdp) {
   51.72  		uint32_t ctr = 0;
   51.73  		/* get RSDT from RSDP */
   51.74 @@ -307,7 +280,7 @@ void tcpa_acpi_init(void)
   51.75  		off = 36;
   51.76  		while ((off + 3) < length) {
   51.77  			/* try all pointers to structures */
   51.78 -			tcpa = (struct acpi_20_tcpa *)rsdt->entry[ctr];
   51.79 +			tcpa = (struct acpi_20_tcpa_clisrv *)rsdt->entry[ctr];
   51.80  			/* valid TCPA ACPI table ? */
   51.81  			if (ACPI_2_0_TCPA_SIGNATURE == tcpa->header.signature
   51.82  			    && acpi_validate_entry(&tcpa->header) == 0) {
   51.83 @@ -398,7 +371,7 @@ static
   51.84  unsigned char *tcpa_get_lasa_base_ptr(void)
   51.85  {
   51.86  	unsigned char *lasa = 0;
   51.87 -	struct acpi_20_tcpa *tcpa = tcpa_acpi.tcpa_ptr;
   51.88 +	struct acpi_20_tcpa_clisrv *tcpa = tcpa_acpi.tcpa_ptr;
   51.89  	if (tcpa != 0) {
   51.90  		uint32_t class = tcpa->platform_class;
   51.91  		if (class == TCPA_ACPI_CLASS_CLIENT) {
   51.92 @@ -416,7 +389,7 @@ static
   51.93  uint32_t tcpa_get_laml(void)
   51.94  {
   51.95  	uint32_t laml = 0;
   51.96 -	struct acpi_20_tcpa *tcpa = tcpa_acpi.tcpa_ptr;
   51.97 +	struct acpi_20_tcpa_clisrv *tcpa = tcpa_acpi.tcpa_ptr;
   51.98  	if (tcpa != 0) {
   51.99  		uint32_t class = tcpa->platform_class;
  51.100  		if (class == TCPA_ACPI_CLASS_CLIENT) {
    52.1 --- a/tools/firmware/rombios/32bit/tcgbios/tcgbios.h	Thu Aug 07 11:47:34 2008 +0900
    52.2 +++ b/tools/firmware/rombios/32bit/tcgbios/tcgbios.h	Thu Aug 07 11:57:34 2008 +0900
    52.3 @@ -1,7 +1,6 @@
    52.4  #ifndef TCGBIOS_H
    52.5  #define TCGBIOS_H
    52.6  
    52.7 -
    52.8  /* TCPA ACPI definitions */
    52.9  #define TCPA_ACPI_CLASS_CLIENT          0
   52.10  #define TCPA_ACPI_CLASS_SERVER          1
   52.11 @@ -117,15 +116,8 @@
   52.12  /* address of locality 0 (TIS) */
   52.13  #define TPM_TIS_BASE_ADDRESS        0xfed40000
   52.14  
   52.15 -#define ASCII32(a,b,c,d)     ((((Bit32u)a) <<  0) | (((Bit32u)b) <<  8) | \
   52.16 -                              (((Bit32u)c) << 16) | (((Bit32u)d) << 24)  )
   52.17 -#define ACPI_2_0_TCPA_SIGNATURE ASCII32('T','C','P','A') /* "TCPA" */
   52.18 -
   52.19 -
   52.20  #define STATUS_FLAG_SHUTDOWN                (1 << 0)
   52.21  
   52.22 -#define ACPI_SEGMENT    0xE000
   52.23 -
   52.24  /* Input and Output blocks for the TCG BIOS commands */
   52.25  
   52.26  struct hleei_short
   52.27 @@ -232,37 +224,6 @@ struct pcpes
   52.28  	uint32_t    event;
   52.29  } __attribute__((packed));
   52.30  
   52.31 -
   52.32 -struct acpi_header
   52.33 -{
   52.34 -	uint32_t signature;
   52.35 -	uint32_t length;
   52.36 -	uint8_t  revision;
   52.37 -	uint8_t  checksum;
   52.38 -	uint8_t  oem_id[6];
   52.39 -	uint64_t oem_table_id;
   52.40 -	uint32_t oem_revision;
   52.41 -	uint32_t creator_id;
   52.42 -	uint32_t creator_revision;
   52.43 -} __attribute__((packed));
   52.44 -
   52.45 -struct acpi_20_rsdt {
   52.46 -	struct acpi_header header;
   52.47 -	uint32_t entry[1];
   52.48 -} __attribute__((packed));
   52.49 -
   52.50 -struct acpi_20_rsdp {
   52.51 -	uint64_t signature;
   52.52 -	uint8_t  checksum;
   52.53 -	uint8_t  oem_id[6];
   52.54 -	uint8_t  revision;
   52.55 -	uint32_t rsdt_address;
   52.56 -	uint32_t length;
   52.57 -	uint64_t xsdt_address;
   52.58 -	uint8_t  extended_checksum;
   52.59 -	uint8_t  reserved[3];
   52.60 -} __attribute__((packed));
   52.61 -
   52.62  struct acpi_20_tcpa_client {
   52.63  	uint32_t laml;
   52.64  	uint64_t lasa;
   52.65 @@ -275,7 +236,7 @@ struct acpi_20_tcpa_server {
   52.66  	/* more here */
   52.67  } __attribute__((packed));
   52.68  
   52.69 -struct acpi_20_tcpa {
   52.70 +struct acpi_20_tcpa_clisrv {
   52.71  	struct acpi_header header;
   52.72  	uint16_t platform_class;
   52.73  	union {
    53.1 --- a/tools/firmware/rombios/32bit/util.c	Thu Aug 07 11:47:34 2008 +0900
    53.2 +++ b/tools/firmware/rombios/32bit/util.c	Thu Aug 07 11:57:34 2008 +0900
    53.3 @@ -19,6 +19,7 @@
    53.4   */
    53.5  #include <stdarg.h>
    53.6  #include <stdint.h>
    53.7 +#include "rombios_compat.h"
    53.8  #include "util.h"
    53.9  
   53.10  static void putchar(char c);
   53.11 @@ -92,11 +93,11 @@ int strcmp(const char *cs, const char *c
   53.12  
   53.13  int strncmp(const char *s1, const char *s2, uint32_t n)
   53.14  {
   53.15 -	uint32_t ctr;
   53.16 -	for (ctr = 0; ctr < n; ctr++)
   53.17 -		if (s1[ctr] != s2[ctr])
   53.18 -			return (int)(s1[ctr] - s2[ctr]);
   53.19 -	return 0;
   53.20 +    uint32_t ctr;
   53.21 +    for (ctr = 0; ctr < n; ctr++)
   53.22 +        if (s1[ctr] != s2[ctr])
   53.23 +            return (int)(s1[ctr] - s2[ctr]);
   53.24 +    return 0;
   53.25  }
   53.26  
   53.27  void *memcpy(void *dest, const void *src, unsigned n)
   53.28 @@ -402,3 +403,64 @@ void mssleep(uint32_t waittime)
   53.29          y = x;
   53.30      }
   53.31  }
   53.32 +
   53.33 +/*
   53.34 + * Search for the RSDP ACPI table in the memory starting at addr and
   53.35 + * ending at addr + len - 1.
   53.36 + */
   53.37 +static struct acpi_20_rsdp *__find_rsdp(const void *start, unsigned int len)
   53.38 +{
   53.39 +    char *rsdp = (char *)start;
   53.40 +    char *end = rsdp + len;
   53.41 +    /* scan memory in steps of 16 bytes */
   53.42 +    while (rsdp < end) {
   53.43 +        /* check for expected string */
   53.44 +        if (!strncmp(rsdp, "RSD PTR ", 8))
   53.45 +            return (struct acpi_20_rsdp *)rsdp;
   53.46 +        rsdp += 0x10;
   53.47 +    }
   53.48 +    return 0;
   53.49 +}
   53.50 +
   53.51 +struct acpi_20_rsdp *find_rsdp(void)
   53.52 +{
   53.53 +    struct acpi_20_rsdp *rsdp;
   53.54 +    uint16_t ebda_seg;
   53.55 +
   53.56 +    ebda_seg = *(uint16_t *)ADDR_FROM_SEG_OFF(0x40, 0xe);
   53.57 +    rsdp = __find_rsdp((void *)(ebda_seg << 16), 1024);
   53.58 +    if (!rsdp)
   53.59 +        rsdp = __find_rsdp((void *)0xE0000, 0x20000);
   53.60 +
   53.61 +    return rsdp;
   53.62 +}
   53.63 +
   53.64 +uint32_t get_s3_waking_vector(void)
   53.65 +{
   53.66 +    struct acpi_20_rsdp *rsdp = find_rsdp();
   53.67 +    struct acpi_20_xsdt *xsdt;
   53.68 +    struct acpi_20_fadt *fadt;
   53.69 +    struct acpi_20_facs *facs;
   53.70 +    uint32_t vector;
   53.71 +
   53.72 +    if (!rsdp)
   53.73 +        return 0;
   53.74 +
   53.75 +    xsdt = (struct acpi_20_xsdt *)(long)rsdp->xsdt_address;
   53.76 +    if (!xsdt)
   53.77 +        return 0;
   53.78 +
   53.79 +    fadt = (struct acpi_20_fadt *)(long)xsdt->entry[0];
   53.80 +    if (!fadt || (fadt->header.signature != ACPI_2_0_FADT_SIGNATURE))
   53.81 +        return 0;
   53.82 +
   53.83 +    facs = (struct acpi_20_facs *)(long)fadt->x_firmware_ctrl;
   53.84 +    if (!facs)
   53.85 +        return 0;
   53.86 +
   53.87 +    vector = facs->x_firmware_waking_vector;
   53.88 +    if (!vector)
   53.89 +        vector = facs->firmware_waking_vector;
   53.90 +
   53.91 +    return vector;
   53.92 +}
    54.1 --- a/tools/firmware/rombios/32bit/util.h	Thu Aug 07 11:47:34 2008 +0900
    54.2 +++ b/tools/firmware/rombios/32bit/util.h	Thu Aug 07 11:57:34 2008 +0900
    54.3 @@ -1,6 +1,8 @@
    54.4  #ifndef UTIL_H
    54.5  #define UTIL_H
    54.6  
    54.7 +#include "../hvmloader/acpi/acpi2_0.h"
    54.8 +
    54.9  void outb(uint16_t addr, uint8_t val);
   54.10  void outw(uint16_t addr, uint16_t val);
   54.11  void outl(uint16_t addr, uint32_t val);
   54.12 @@ -39,5 +41,6 @@ static inline uint32_t mmio_readl(uint32
   54.13  	return *(volatile uint32_t *)addr;
   54.14  }
   54.15  
   54.16 +struct acpi_20_rsdp *find_rsdp(void);
   54.17  
   54.18  #endif
    55.1 --- a/tools/firmware/rombios/32bitgateway.c	Thu Aug 07 11:47:34 2008 +0900
    55.2 +++ b/tools/firmware/rombios/32bitgateway.c	Thu Aug 07 11:57:34 2008 +0900
    55.3 @@ -356,6 +356,9 @@ Upcall:
    55.4  	call _store_returnaddress	; store away
    55.5  	pop ax
    55.6  
    55.7 +	; XXX GDT munging requires ROM to be writable!
    55.8 +	call _enable_rom_write_access
    55.9 +
   55.10  	rol bx, #2
   55.11  	mov si, #jmptable
   55.12  	seg cs
   55.13 @@ -382,6 +385,8 @@ Upcall:
   55.14  	mov bp,sp
   55.15  	push eax			; preserve work register
   55.16  
   55.17 +	call _disable_rom_write_access
   55.18 +
   55.19  	call _get_returnaddress
   55.20  	mov 2[bp], ax			; 16bit return address onto stack
   55.21  
   55.22 @@ -408,3 +413,10 @@ ASM_END
   55.23  #include "32bitgateway.h"
   55.24  
   55.25  #include "tcgbios.c"
   55.26 +
   55.27 +Bit32u get_s3_waking_vector()
   55.28 +{
   55.29 +	ASM_START
   55.30 +	DoUpcall(IDX_GET_S3_WAKING_VECTOR)
   55.31 +	ASM_END
   55.32 +}
    56.1 --- a/tools/firmware/rombios/32bitprotos.h	Thu Aug 07 11:47:34 2008 +0900
    56.2 +++ b/tools/firmware/rombios/32bitprotos.h	Thu Aug 07 11:57:34 2008 +0900
    56.3 @@ -17,8 +17,8 @@
    56.4  #define IDX_TCPA_IPL                       10
    56.5  #define IDX_TCPA_INITIALIZE_TPM            11
    56.6  #define IDX_TCPA_MEASURE_POST              12
    56.7 -
    56.8 -#define IDX_LAST                           13 /* keep last! */
    56.9 +#define IDX_GET_S3_WAKING_VECTOR           13
   56.10 +#define IDX_LAST                           14 /* keep last! */
   56.11  
   56.12  #ifdef GCC_PROTOS
   56.13    #define PARMS(x...) x
   56.14 @@ -42,4 +42,6 @@ void tcpa_ipl( PARMS(Bit32u bootcd,Bit32
   56.15  void tcpa_measure_post( PARMS(Bit32u from, Bit32u to) );
   56.16  Bit32u tcpa_initialize_tpm( PARMS(Bit32u physpres) );
   56.17  
   56.18 +Bit32u get_s3_waking_vector( PARMS(void) );
   56.19 +
   56.20  #endif
    57.1 --- a/tools/firmware/rombios/Makefile	Thu Aug 07 11:47:34 2008 +0900
    57.2 +++ b/tools/firmware/rombios/Makefile	Thu Aug 07 11:57:34 2008 +0900
    57.3 @@ -4,7 +4,8 @@ include $(XEN_ROOT)/tools/Rules.mk
    57.4  SUBDIRS := 32bit
    57.5  
    57.6  .PHONY: all
    57.7 -all: subdirs-all BIOS-bochs-latest
    57.8 +all: subdirs-all
    57.9 +	$(MAKE) BIOS-bochs-latest
   57.10  
   57.11  .PHONY: clean
   57.12  clean: subdirs-clean
    58.1 --- a/tools/firmware/rombios/rombios.c	Thu Aug 07 11:47:34 2008 +0900
    58.2 +++ b/tools/firmware/rombios/rombios.c	Thu Aug 07 11:57:34 2008 +0900
    58.3 @@ -738,7 +738,9 @@ typedef struct {
    58.4    // EBDA must be at most 768 bytes; it lives at 0x9fc00, and the boot 
    58.5    // device tables are at 0x9ff00 -- 0x9ffff
    58.6    typedef struct {
    58.7 -    unsigned char filler1[0x3D];
    58.8 +    unsigned char ebda_size;
    58.9 +    unsigned char cmos_shutdown_status;
   58.10 +    unsigned char filler1[0x3B];
   58.11  
   58.12      // FDPT - Can be splitted in data members if needed
   58.13      unsigned char fdpt0[0x10];
   58.14 @@ -757,6 +759,7 @@ typedef struct {
   58.15      upcall_t upcall;
   58.16      } ebda_data_t;
   58.17    
   58.18 +  #define EBDA_CMOS_SHUTDOWN_STATUS_OFFSET 1
   58.19    #define EbdaData ((ebda_data_t *) 0)
   58.20  
   58.21    // for access to the int13ext structure
   58.22 @@ -1464,20 +1467,31 @@ copy_e820_table()
   58.23  }
   58.24  
   58.25  void
   58.26 -disable_rom_write_access()
   58.27 +set_rom_write_access(action)
   58.28 +  Bit16u action;
   58.29  {
   58.30      Bit16u off = (Bit16u)&((struct bios_info *)0)->xen_pfiob;
   58.31  ASM_START
   58.32 -    mov si,.disable_rom_write_access.off[bp]
   58.33 +    mov si,.set_rom_write_access.off[bp]
   58.34      push ds
   58.35      mov ax,#(ACPI_PHYSICAL_ADDRESS >> 4)
   58.36      mov ds,ax
   58.37      mov dx,[si]
   58.38      pop ds
   58.39 -    mov ax,#PFFLAG_ROM_LOCK
   58.40 +    mov ax,.set_rom_write_access.action[bp]
   58.41      out dx,al
   58.42  ASM_END
   58.43  }
   58.44 +
   58.45 +void enable_rom_write_access()
   58.46 +{
   58.47 +    set_rom_write_access(0);
   58.48 +}
   58.49 +
   58.50 +void disable_rom_write_access()
   58.51 +{
   58.52 +    set_rom_write_access(PFFLAG_ROM_LOCK);
   58.53 +}
   58.54      
   58.55  #endif /* HVMASSIST */
   58.56  
   58.57 @@ -2325,78 +2339,38 @@ debugger_off()
   58.58    outb(0xfedc, 0x00);
   58.59  }
   58.60  
   58.61 -/* according to memory layout defined in acpi_build_tables(),
   58.62 -   acpi FACS table is located in ACPI_PHYSICAL_ADDRESS(0xEA000) */
   58.63 -#define ACPI_FACS_ADDRESS 0xEA000
   58.64 -#define ACPI_FACS_OFFSET 0x10
   58.65 -/* S3 resume status in CMOS 0Fh shutdown status byte*/
   58.66 -
   58.67 -Bit32u facs_get32(offs)
   58.68 -Bit16u offs;
   58.69 -{
   58.70 -ASM_START
   58.71 -  push bp
   58.72 -  mov  bp, sp
   58.73 -
   58.74 -    push ds
   58.75 -    mov ax, #(ACPI_FACS_ADDRESS >> 4)
   58.76 -    mov ds, ax
   58.77 -
   58.78 -    mov bx, 4[bp]
   58.79 -    mov ax, [bx]
   58.80 -    mov dx, 2[bx]
   58.81 -    pop ds
   58.82 -
   58.83 -  pop  bp
   58.84 -ASM_END
   58.85 -}
   58.86 -
   58.87 -
   58.88  void 
   58.89  s3_resume()
   58.90  {
   58.91      Bit32u s3_wakeup_vector;
   58.92 -    extern Bit16u s3_wakeup_ip;
   58.93 -    extern Bit16u s3_wakeup_cs;
   58.94 -    extern Bit8u s3_resume_flag;
   58.95 +    Bit16u s3_wakeup_ip, s3_wakeup_cs;
   58.96 +    Bit8u cmos_shutdown_status;
   58.97  
   58.98  ASM_START
   58.99      push ds
  58.100 -    mov ax, #0xF000
  58.101 +    push ax
  58.102 +    mov ax, #EBDA_SEG
  58.103      mov ds, ax
  58.104 +    mov al, [EBDA_CMOS_SHUTDOWN_STATUS_OFFSET]
  58.105 +    mov .s3_resume.cmos_shutdown_status[bp], al
  58.106 +    pop ax
  58.107 +    pop ds
  58.108  ASM_END
  58.109  
  58.110 -    if (s3_resume_flag!=CMOS_SHUTDOWN_S3){
  58.111 -        goto s3_out;
  58.112 -    }
  58.113 -    s3_resume_flag = 0;
  58.114 -
  58.115 -    /* get x_firmware_waking_vector */
  58.116 -    s3_wakeup_vector = facs_get32(ACPI_FACS_OFFSET+24);
  58.117 -    if (!s3_wakeup_vector) {
  58.118 -        /* get firmware_waking_vector */
  58.119 -	s3_wakeup_vector = facs_get32(ACPI_FACS_OFFSET+12);
  58.120 -    	if (!s3_wakeup_vector) {
  58.121 -            goto s3_out;
  58.122 -	}
  58.123 -    }
  58.124 -
  58.125 -    /* setup wakeup vector */
  58.126 +    if (cmos_shutdown_status != CMOS_SHUTDOWN_S3)
  58.127 +        return;
  58.128 +
  58.129 +    s3_wakeup_vector = get_s3_waking_vector();
  58.130 +    if (!s3_wakeup_vector)
  58.131 +        return;
  58.132 +
  58.133      s3_wakeup_ip = s3_wakeup_vector & 0xF;
  58.134      s3_wakeup_cs = s3_wakeup_vector >> 4;
  58.135  
  58.136  ASM_START
  58.137 -    jmpf [_s3_wakeup_ip]
  58.138 -
  58.139 -; S3 data
  58.140 -_s3_wakeup_ip:    dw 0x0a      
  58.141 -_s3_wakeup_cs:    dw 0x0      
  58.142 -_s3_resume_flag:  db 0   ; set at POST time by CMOS[0xF] shutdown status
  58.143 -ASM_END
  58.144 -
  58.145 -s3_out:
  58.146 -ASM_START
  58.147 -   pop ds 
  58.148 +    push .s3_resume.s3_wakeup_cs[bp]
  58.149 +    push .s3_resume.s3_wakeup_ip[bp]
  58.150 +    retf
  58.151  ASM_END
  58.152  }
  58.153  
  58.154 @@ -9865,52 +9839,9 @@ post:
  58.155  
  58.156    ;; Examine CMOS shutdown status.
  58.157    mov al, bl
  58.158 -
  58.159 -  ;; 0xFE S3 resume
  58.160 -  cmp AL, #0xFE
  58.161 -  jnz not_s3_resume
  58.162 -
  58.163 -  ;; set S3 resume flag
  58.164 -  mov dx, #0xF000
  58.165 +  mov dx, #EBDA_SEG
  58.166    mov ds, dx
  58.167 -  mov [_s3_resume_flag], AL
  58.168 -  jmp normal_post
  58.169 -
  58.170 -not_s3_resume:
  58.171 -
  58.172 -  ;; 0x00, 0x09, 0x0D+ = normal startup
  58.173 -  cmp AL, #0x00
  58.174 -  jz normal_post
  58.175 -  cmp AL, #0x0d
  58.176 -  jae normal_post
  58.177 -  cmp AL, #0x09
  58.178 -  je normal_post
  58.179 -
  58.180 -  ;; 0x05 = eoi + jmp via [0x40:0x67] jump
  58.181 -  cmp al, #0x05
  58.182 -  je  eoi_jmp_post
  58.183 -
  58.184 -  ;; Examine CMOS shutdown status.
  58.185 -  ;;  0x01,0x02,0x03,0x04,0x06,0x07,0x08, 0x0a, 0x0b, 0x0c = Unimplemented shutdown status.
  58.186 -  push bx
  58.187 -  call _shutdown_status_panic
  58.188 -
  58.189 -#if 0 
  58.190 -  HALT(__LINE__)
  58.191 -  ;
  58.192 -  ;#if 0
  58.193 -  ;  0xb0, 0x20,       /* mov al, #0x20 */
  58.194 -  ;  0xe6, 0x20,       /* out 0x20, al    ;send EOI to PIC */
  58.195 -  ;#endif
  58.196 -  ;
  58.197 -  pop es
  58.198 -  pop ds
  58.199 -  popa
  58.200 -  iret
  58.201 -#endif
  58.202 -
  58.203 -normal_post:
  58.204 -  ; case 0: normal startup
  58.205 +  mov [EBDA_CMOS_SHUTDOWN_STATUS_OFFSET], AL
  58.206  
  58.207    cli
  58.208    mov  ax, #0xfffe
  58.209 @@ -9929,8 +9860,6 @@ normal_post:
  58.210  
  58.211    call _log_bios_start
  58.212  
  58.213 -  call _clobber_entry_point
  58.214 -
  58.215    ;; set all interrupts to default handler
  58.216    mov  bx, #0x0000    ;; offset index
  58.217    mov  cx, #0x0100    ;; counter (256 interrupts)
  58.218 @@ -10123,8 +10052,11 @@ post_default_ints:
  58.219    out  0xa1, AL ;slave  pic: unmask IRQ 12, 13, 14
  58.220  
  58.221  #ifdef HVMASSIST
  58.222 +  call _enable_rom_write_access
  58.223 +  call _clobber_entry_point
  58.224    call _copy_e820_table
  58.225    call smbios_init
  58.226 +  call _disable_rom_write_access
  58.227  #endif
  58.228  
  58.229    call _init_boot_vectors
  58.230 @@ -10175,10 +10107,6 @@ post_default_ints:
  58.231    call tcpa_post_part2
  58.232  #endif
  58.233  
  58.234 -#ifdef HVMASSIST
  58.235 -  call _disable_rom_write_access
  58.236 -#endif 
  58.237 -
  58.238    ;; Start the boot sequence.   See the comments in int19_relocated 
  58.239    ;; for why we use INT 18h instead of INT 19h here.
  58.240    int  #0x18
    59.1 --- a/tools/fs-back/fs-backend.c	Thu Aug 07 11:47:34 2008 +0900
    59.2 +++ b/tools/fs-back/fs-backend.c	Thu Aug 07 11:57:34 2008 +0900
    59.3 @@ -16,7 +16,7 @@ static struct fs_export *fs_exports = NU
    59.4  static int export_id = 0;
    59.5  static int mount_id = 0;
    59.6  
    59.7 -void dispatch_response(struct mount *mount, int priv_req_id)
    59.8 +static void dispatch_response(struct fs_mount *mount, int priv_req_id)
    59.9  {
   59.10      int i;
   59.11      struct fs_op *op;
   59.12 @@ -41,7 +41,7 @@ void dispatch_response(struct mount *mou
   59.13      add_id_to_freelist(priv_req_id, mount->freelist);
   59.14  }
   59.15  
   59.16 -static void handle_aio_events(struct mount *mount)
   59.17 +static void handle_aio_events(struct fs_mount *mount)
   59.18  {
   59.19      int fd, ret, count, i, notify;
   59.20      evtchn_port_t port;
   59.21 @@ -103,7 +103,7 @@ read_event_channel:
   59.22  }
   59.23  
   59.24  
   59.25 -void allocate_request_array(struct mount *mount)
   59.26 +static void allocate_request_array(struct fs_mount *mount)
   59.27  {
   59.28      int i, nr_entries = mount->nr_entries;
   59.29      struct fs_request *requests;
   59.30 @@ -123,10 +123,10 @@ void allocate_request_array(struct mount
   59.31  }
   59.32  
   59.33  
   59.34 -void* handle_mount(void *data)
   59.35 +static void *handle_mount(void *data)
   59.36  {
   59.37      int more, notify;
   59.38 -    struct mount *mount = (struct mount *)data;
   59.39 +    struct fs_mount *mount = (struct fs_mount *)data;
   59.40      
   59.41      printf("Starting a thread for mount: %d\n", mount->mount_id);
   59.42      allocate_request_array(mount);
   59.43 @@ -147,7 +147,8 @@ moretodo:
   59.44              int i;
   59.45              struct fs_op *op;
   59.46  
   59.47 -            printf("Got a request at %d\n", cons);
   59.48 +            printf("Got a request at %d (of %d)\n", 
   59.49 +                    cons, RING_SIZE(&mount->ring));
   59.50              req = RING_GET_REQUEST(&mount->ring, cons);
   59.51              printf("Request type=%d\n", req->type); 
   59.52              for(i=0;;i++)
   59.53 @@ -193,11 +194,12 @@ moretodo:
   59.54  
   59.55  static void handle_connection(int frontend_dom_id, int export_id, char *frontend)
   59.56  {
   59.57 -    struct mount *mount;
   59.58 +    struct fs_mount *mount;
   59.59      struct fs_export *export;
   59.60      int evt_port;
   59.61      pthread_t handling_thread;
   59.62      struct fsif_sring *sring;
   59.63 +    uint32_t dom_ids[MAX_RING_SIZE];
   59.64      int i;
   59.65  
   59.66      printf("Handling connection from dom=%d, for export=%d\n", 
   59.67 @@ -216,13 +218,13 @@ static void handle_connection(int fronte
   59.68          return;
   59.69      }
   59.70  
   59.71 -    mount = (struct mount*)malloc(sizeof(struct mount));
   59.72 +    mount = (struct fs_mount*)malloc(sizeof(struct fs_mount));
   59.73      mount->dom_id = frontend_dom_id;
   59.74      mount->export = export;
   59.75      mount->mount_id = mount_id++;
   59.76      xenbus_read_mount_request(mount, frontend);
   59.77      printf("Frontend found at: %s (gref=%d, evtchn=%d)\n", 
   59.78 -            mount->frontend, mount->gref, mount->remote_evtchn);
   59.79 +            mount->frontend, mount->grefs[0], mount->remote_evtchn);
   59.80      xenbus_write_backend_node(mount);
   59.81      mount->evth = -1;
   59.82      mount->evth = xc_evtchn_open(); 
   59.83 @@ -235,11 +237,15 @@ static void handle_connection(int fronte
   59.84      mount->gnth = -1;
   59.85      mount->gnth = xc_gnttab_open(); 
   59.86      assert(mount->gnth != -1);
   59.87 -    sring = xc_gnttab_map_grant_ref(mount->gnth,
   59.88 -                                    mount->dom_id,
   59.89 -                                    mount->gref,
   59.90 -                                    PROT_READ | PROT_WRITE);
   59.91 -    BACK_RING_INIT(&mount->ring, sring, XC_PAGE_SIZE);
   59.92 +    for(i=0; i<mount->shared_ring_size; i++)
   59.93 +        dom_ids[i] = mount->dom_id;
   59.94 +    sring = xc_gnttab_map_grant_refs(mount->gnth,
   59.95 +                                     mount->shared_ring_size,
   59.96 +                                     dom_ids,
   59.97 +                                     mount->grefs,
   59.98 +                                     PROT_READ | PROT_WRITE);
   59.99 +
  59.100 +    BACK_RING_INIT(&mount->ring, sring, mount->shared_ring_size * XC_PAGE_SIZE);
  59.101      mount->nr_entries = mount->ring.nr_ents; 
  59.102      for (i = 0; i < MAX_FDS; i++)
  59.103          mount->fds[i] = -1;
  59.104 @@ -287,7 +293,7 @@ next_select:
  59.105      } while (1);
  59.106  }
  59.107  
  59.108 -struct fs_export* create_export(char *name, char *export_path)
  59.109 +static struct fs_export* create_export(char *name, char *export_path)
  59.110  {
  59.111      struct fs_export *curr_export, **last_export;
  59.112  
    60.1 --- a/tools/fs-back/fs-backend.h	Thu Aug 07 11:47:34 2008 +0900
    60.2 +++ b/tools/fs-back/fs-backend.h	Thu Aug 07 11:57:34 2008 +0900
    60.3 @@ -13,6 +13,7 @@
    60.4  #define EXPORTS_NODE        ROOT_NODE"/"EXPORTS_SUBNODE
    60.5  #define WATCH_NODE          EXPORTS_NODE"/requests"
    60.6  #define MAX_FDS             16
    60.7 +#define MAX_RING_SIZE       16
    60.8  
    60.9  struct fs_export
   60.10  {
   60.11 @@ -26,22 +27,24 @@ struct fs_request
   60.12  {
   60.13      int active;
   60.14      void *page;                         /* Pointer to mapped grant */
   60.15 +    int count;
   60.16      struct fsif_request req_shadow;
   60.17      struct aiocb aiocb; 
   60.18  };
   60.19  
   60.20  
   60.21 -struct mount
   60.22 +struct fs_mount
   60.23  {
   60.24      struct fs_export *export;
   60.25      int dom_id;
   60.26      char *frontend;
   60.27      int mount_id;                     /* = backend id */
   60.28 -    grant_ref_t gref;
   60.29 +    grant_ref_t grefs[MAX_RING_SIZE];
   60.30      evtchn_port_t remote_evtchn;
   60.31      int evth;                         /* Handle to the event channel */
   60.32      evtchn_port_t local_evtchn;
   60.33      int gnth;
   60.34 +    int shared_ring_size;             /* in pages */
   60.35      struct fsif_back_ring ring;
   60.36      int nr_entries;
   60.37      struct fs_request *requests;
   60.38 @@ -56,17 +59,17 @@ extern struct xs_handle *xsh;
   60.39  bool xenbus_create_request_node(void);
   60.40  int xenbus_register_export(struct fs_export *export);
   60.41  int xenbus_get_watch_fd(void);
   60.42 -void xenbus_read_mount_request(struct mount *mount, char *frontend);
   60.43 -void xenbus_write_backend_node(struct mount *mount);
   60.44 -void xenbus_write_backend_ready(struct mount *mount);
   60.45 +void xenbus_read_mount_request(struct fs_mount *mount, char *frontend);
   60.46 +void xenbus_write_backend_node(struct fs_mount *mount);
   60.47 +void xenbus_write_backend_ready(struct fs_mount *mount);
   60.48  
   60.49  /* File operations, implemented in fs-ops.c */
   60.50  struct fs_op
   60.51  {
   60.52      int type;       /* Type of request (from fsif.h) this handlers 
   60.53                         are responsible for */
   60.54 -    void (*dispatch_handler)(struct mount *mount, struct fsif_request *req);
   60.55 -    void (*response_handler)(struct mount *mount, struct fs_request *req);
   60.56 +    void (*dispatch_handler)(struct fs_mount *mount, struct fsif_request *req);
   60.57 +    void (*response_handler)(struct fs_mount *mount, struct fs_request *req);
   60.58  };
   60.59  
   60.60  /* This NULL terminated array of all file requests handlers */
    61.1 --- a/tools/fs-back/fs-ops.c	Thu Aug 07 11:47:34 2008 +0900
    61.2 +++ b/tools/fs-back/fs-ops.c	Thu Aug 07 11:57:34 2008 +0900
    61.3 @@ -10,7 +10,7 @@
    61.4  #include <sys/mman.h>
    61.5  #include <sys/types.h>
    61.6  #include <sys/stat.h>
    61.7 -#include <sys/vfs.h>
    61.8 +#include <sys/statvfs.h>
    61.9  #include <sys/mount.h>
   61.10  #include <unistd.h>
   61.11  #include "fs-backend.h"
   61.12 @@ -23,7 +23,7 @@
   61.13  #define BUFFER_SIZE 1024
   61.14  
   61.15  
   61.16 -unsigned short get_request(struct mount *mount, struct fsif_request *req)
   61.17 +static unsigned short get_request(struct fs_mount *mount, struct fsif_request *req)
   61.18  {
   61.19      unsigned short id = get_id_from_freelist(mount->freelist); 
   61.20  
   61.21 @@ -34,7 +34,7 @@ unsigned short get_request(struct mount 
   61.22      return id;
   61.23  }
   61.24  
   61.25 -int get_fd(struct mount *mount)
   61.26 +static int get_fd(struct fs_mount *mount)
   61.27  {
   61.28      int i;
   61.29  
   61.30 @@ -45,7 +45,7 @@ int get_fd(struct mount *mount)
   61.31  }
   61.32  
   61.33  
   61.34 -void dispatch_file_open(struct mount *mount, struct fsif_request *req)
   61.35 +static void dispatch_file_open(struct fs_mount *mount, struct fsif_request *req)
   61.36  {
   61.37      char *file_name, full_path[BUFFER_SIZE];
   61.38      int fd;
   61.39 @@ -93,7 +93,7 @@ void dispatch_file_open(struct mount *mo
   61.40      rsp->ret_val = (uint64_t)fd;
   61.41  }
   61.42  
   61.43 -void dispatch_file_close(struct mount *mount, struct fsif_request *req)
   61.44 +static void dispatch_file_close(struct fs_mount *mount, struct fsif_request *req)
   61.45  {
   61.46      int ret;
   61.47      RING_IDX rsp_idx;
   61.48 @@ -122,19 +122,25 @@ void dispatch_file_close(struct mount *m
   61.49      rsp->id = req_id; 
   61.50      rsp->ret_val = (uint64_t)ret;
   61.51  }
   61.52 -void dispatch_file_read(struct mount *mount, struct fsif_request *req)
   61.53 +
   61.54 +#define MAX_GNTS 16
   61.55 +static void dispatch_file_read(struct fs_mount *mount, struct fsif_request *req)
   61.56  {
   61.57      void *buf;
   61.58 -    int fd;
   61.59 +    int fd, i, count;
   61.60      uint16_t req_id;
   61.61      unsigned short priv_id;
   61.62      struct fs_request *priv_req;
   61.63  
   61.64      /* Read the request */
   61.65 -    buf = xc_gnttab_map_grant_ref(mount->gnth,
   61.66 -                                  mount->dom_id,
   61.67 -                                  req->u.fread.gref,
   61.68 -                                  PROT_WRITE);
   61.69 +    assert(req->u.fread.len > 0); 
   61.70 +    count = (req->u.fread.len - 1) / XC_PAGE_SIZE + 1;
   61.71 +    assert(count <= FSIF_NR_READ_GNTS);
   61.72 +    buf = xc_gnttab_map_domain_grant_refs(mount->gnth,
   61.73 +                                          count,
   61.74 +                                          mount->dom_id,
   61.75 +                                          req->u.fread.grefs,
   61.76 +                                          PROT_WRITE);
   61.77     
   61.78      req_id = req->id;
   61.79      printf("File read issued for FD=%d (len=%"PRIu64", offest=%"PRIu64")\n", 
   61.80 @@ -149,6 +155,7 @@ void dispatch_file_read(struct mount *mo
   61.81      printf("Private id is: %d\n", priv_id);
   61.82      priv_req = &mount->requests[priv_id];
   61.83      priv_req->page = buf;
   61.84 +    priv_req->count = count;
   61.85  
   61.86      /* Dispatch AIO read request */
   61.87      bzero(&priv_req->aiocb, sizeof(struct aiocb));
   61.88 @@ -164,14 +171,16 @@ out:
   61.89      mount->ring.req_cons++;
   61.90  }
   61.91  
   61.92 -void end_file_read(struct mount *mount, struct fs_request *priv_req)
   61.93 +static void end_file_read(struct fs_mount *mount, struct fs_request *priv_req)
   61.94  {
   61.95      RING_IDX rsp_idx;
   61.96      fsif_response_t *rsp;
   61.97      uint16_t req_id;
   61.98  
   61.99      /* Release the grant */
  61.100 -    assert(xc_gnttab_munmap(mount->gnth, priv_req->page, 1) == 0);
  61.101 +    assert(xc_gnttab_munmap(mount->gnth, 
  61.102 +                            priv_req->page, 
  61.103 +                            priv_req->count) == 0);
  61.104  
  61.105      /* Get a response from the ring */
  61.106      rsp_idx = mount->ring.rsp_prod_pvt++;
  61.107 @@ -182,19 +191,23 @@ void end_file_read(struct mount *mount, 
  61.108      rsp->ret_val = (uint64_t)aio_return(&priv_req->aiocb);
  61.109  }
  61.110  
  61.111 -void dispatch_file_write(struct mount *mount, struct fsif_request *req)
  61.112 +static void dispatch_file_write(struct fs_mount *mount, struct fsif_request *req)
  61.113  {
  61.114      void *buf;
  61.115 -    int fd;
  61.116 +    int fd, count, i;
  61.117      uint16_t req_id;
  61.118      unsigned short priv_id;
  61.119      struct fs_request *priv_req;
  61.120  
  61.121      /* Read the request */
  61.122 -    buf = xc_gnttab_map_grant_ref(mount->gnth,
  61.123 -                                  mount->dom_id,
  61.124 -                                  req->u.fwrite.gref,
  61.125 -                                  PROT_READ);
  61.126 +    assert(req->u.fwrite.len > 0); 
  61.127 +    count = (req->u.fwrite.len - 1) / XC_PAGE_SIZE + 1;
  61.128 +    assert(count <= FSIF_NR_WRITE_GNTS);
  61.129 +    buf = xc_gnttab_map_domain_grant_refs(mount->gnth,
  61.130 +                                          count,
  61.131 +                                          mount->dom_id,
  61.132 +                                          req->u.fwrite.grefs,
  61.133 +                                          PROT_READ);
  61.134     
  61.135      req_id = req->id;
  61.136      printf("File write issued for FD=%d (len=%"PRIu64", offest=%"PRIu64")\n", 
  61.137 @@ -209,6 +222,7 @@ void dispatch_file_write(struct mount *m
  61.138      printf("Private id is: %d\n", priv_id);
  61.139      priv_req = &mount->requests[priv_id];
  61.140      priv_req->page = buf;
  61.141 +    priv_req->count = count;
  61.142  
  61.143      /* Dispatch AIO write request */
  61.144      bzero(&priv_req->aiocb, sizeof(struct aiocb));
  61.145 @@ -224,14 +238,16 @@ void dispatch_file_write(struct mount *m
  61.146      mount->ring.req_cons++;
  61.147  }
  61.148  
  61.149 -void end_file_write(struct mount *mount, struct fs_request *priv_req)
  61.150 +static void end_file_write(struct fs_mount *mount, struct fs_request *priv_req)
  61.151  {
  61.152      RING_IDX rsp_idx;
  61.153      fsif_response_t *rsp;
  61.154      uint16_t req_id;
  61.155  
  61.156      /* Release the grant */
  61.157 -    assert(xc_gnttab_munmap(mount->gnth, priv_req->page, 1) == 0);
  61.158 +    assert(xc_gnttab_munmap(mount->gnth, 
  61.159 +                            priv_req->page, 
  61.160 +                            priv_req->count) == 0);
  61.161      
  61.162      /* Get a response from the ring */
  61.163      rsp_idx = mount->ring.rsp_prod_pvt++;
  61.164 @@ -242,7 +258,7 @@ void end_file_write(struct mount *mount,
  61.165      rsp->ret_val = (uint64_t)aio_return(&priv_req->aiocb);
  61.166  }
  61.167  
  61.168 -void dispatch_stat(struct mount *mount, struct fsif_request *req)
  61.169 +static void dispatch_stat(struct fs_mount *mount, struct fsif_request *req)
  61.170  {
  61.171      struct fsif_stat_response *buf;
  61.172      struct stat stat;
  61.173 @@ -251,12 +267,6 @@ void dispatch_stat(struct mount *mount, 
  61.174      RING_IDX rsp_idx;
  61.175      fsif_response_t *rsp;
  61.176  
  61.177 -    /* Read the request */
  61.178 -    buf = xc_gnttab_map_grant_ref(mount->gnth,
  61.179 -                                  mount->dom_id,
  61.180 -                                  req->u.fstat.gref,
  61.181 -                                  PROT_WRITE);
  61.182 -   
  61.183      req_id = req->id;
  61.184      if (req->u.fstat.fd < MAX_FDS)
  61.185          fd = mount->fds[req->u.fstat.fd];
  61.186 @@ -272,38 +282,35 @@ void dispatch_stat(struct mount *mount, 
  61.187      /* Stat, and create the response */ 
  61.188      ret = fstat(fd, &stat);
  61.189      printf("Mode=%o, uid=%d, a_time=%ld\n",
  61.190 -            stat.st_mode, stat.st_uid, stat.st_atime);
  61.191 -    buf->stat_mode  = stat.st_mode;
  61.192 -    buf->stat_uid   = stat.st_uid;
  61.193 -    buf->stat_gid   = stat.st_gid;
  61.194 -#ifdef BLKGETSIZE
  61.195 -    if (S_ISBLK(stat.st_mode)) {
  61.196 -	unsigned long sectors;
  61.197 -	if (ioctl(fd, BLKGETSIZE, &sectors)) {
  61.198 -	    perror("getting device size\n");
  61.199 -	    buf->stat_size = 0;
  61.200 -	} else
  61.201 -	    buf->stat_size = sectors << 9;
  61.202 -    } else
  61.203 -#endif
  61.204 -	buf->stat_size  = stat.st_size;
  61.205 -    buf->stat_atime = stat.st_atime;
  61.206 -    buf->stat_mtime = stat.st_mtime;
  61.207 -    buf->stat_ctime = stat.st_ctime;
  61.208 -
  61.209 -    /* Release the grant */
  61.210 -    assert(xc_gnttab_munmap(mount->gnth, buf, 1) == 0);
  61.211 +            stat.st_mode, stat.st_uid, (long)stat.st_atime);
  61.212      
  61.213      /* Get a response from the ring */
  61.214      rsp_idx = mount->ring.rsp_prod_pvt++;
  61.215      printf("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
  61.216      rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
  61.217      rsp->id = req_id; 
  61.218 -    rsp->ret_val = (uint64_t)ret;
  61.219 +    rsp->fstat.stat_ret = (uint32_t)ret;
  61.220 +    rsp->fstat.stat_mode  = stat.st_mode;
  61.221 +    rsp->fstat.stat_uid   = stat.st_uid;
  61.222 +    rsp->fstat.stat_gid   = stat.st_gid;
  61.223 +#ifdef BLKGETSIZE
  61.224 +    if (S_ISBLK(stat.st_mode)) {
  61.225 +	unsigned long sectors;
  61.226 +	if (ioctl(fd, BLKGETSIZE, &sectors)) {
  61.227 +	    perror("getting device size\n");
  61.228 +	    rsp->fstat.stat_size = 0;
  61.229 +	} else
  61.230 +	    rsp->fstat.stat_size = sectors << 9;
  61.231 +    } else
  61.232 +#endif
  61.233 +	rsp->fstat.stat_size  = stat.st_size;
  61.234 +    rsp->fstat.stat_atime = stat.st_atime;
  61.235 +    rsp->fstat.stat_mtime = stat.st_mtime;
  61.236 +    rsp->fstat.stat_ctime = stat.st_ctime;
  61.237  }
  61.238  
  61.239  
  61.240 -void dispatch_truncate(struct mount *mount, struct fsif_request *req)
  61.241 +static void dispatch_truncate(struct fs_mount *mount, struct fsif_request *req)
  61.242  {
  61.243      int fd, ret;
  61.244      uint16_t req_id;
  61.245 @@ -335,7 +342,7 @@ void dispatch_truncate(struct mount *mou
  61.246      rsp->ret_val = (uint64_t)ret;
  61.247  }
  61.248  
  61.249 -void dispatch_remove(struct mount *mount, struct fsif_request *req)
  61.250 +static void dispatch_remove(struct fs_mount *mount, struct fsif_request *req)
  61.251  {
  61.252      char *file_name, full_path[BUFFER_SIZE];
  61.253      int ret;
  61.254 @@ -374,7 +381,7 @@ void dispatch_remove(struct mount *mount
  61.255  }
  61.256  
  61.257  
  61.258 -void dispatch_rename(struct mount *mount, struct fsif_request *req)
  61.259 +static void dispatch_rename(struct fs_mount *mount, struct fsif_request *req)
  61.260  {
  61.261      char *buf, *old_file_name, *new_file_name;
  61.262      char old_full_path[BUFFER_SIZE], new_full_path[BUFFER_SIZE];
  61.263 @@ -421,7 +428,7 @@ void dispatch_rename(struct mount *mount
  61.264  }
  61.265  
  61.266  
  61.267 -void dispatch_create(struct mount *mount, struct fsif_request *req)
  61.268 +static void dispatch_create(struct fs_mount *mount, struct fsif_request *req)
  61.269  {
  61.270      char *file_name, full_path[BUFFER_SIZE];
  61.271      int ret;
  61.272 @@ -459,7 +466,17 @@ void dispatch_create(struct mount *mount
  61.273      else
  61.274      {
  61.275          printf("Issuing create for file: %s\n", full_path);
  61.276 -        ret = creat(full_path, mode); 
  61.277 +        ret = get_fd(mount);
  61.278 +        if (ret >= 0) {
  61.279 +            int real_fd = creat(full_path, mode); 
  61.280 +            if (real_fd < 0)
  61.281 +                ret = -1;
  61.282 +            else
  61.283 +            {
  61.284 +                mount->fds[ret] = real_fd;
  61.285 +                printf("Got FD: %d for real %d\n", ret, real_fd);
  61.286 +            }
  61.287 +        }
  61.288      }
  61.289      printf("Got ret %d (errno=%d)\n", ret, errno);
  61.290  
  61.291 @@ -471,7 +488,7 @@ void dispatch_create(struct mount *mount
  61.292      rsp->ret_val = (uint64_t)ret;
  61.293  }
  61.294  
  61.295 -void dispatch_list(struct mount *mount, struct fsif_request *req)
  61.296 +static void dispatch_list(struct fs_mount *mount, struct fsif_request *req)
  61.297  {
  61.298      char *file_name, *buf, full_path[BUFFER_SIZE];
  61.299      uint32_t offset, nr_files, error_code; 
  61.300 @@ -541,7 +558,7 @@ error_out:
  61.301      rsp->ret_val = ret_val;
  61.302  }
  61.303  
  61.304 -void dispatch_chmod(struct mount *mount, struct fsif_request *req)
  61.305 +static void dispatch_chmod(struct fs_mount *mount, struct fsif_request *req)
  61.306  {
  61.307      int fd, ret;
  61.308      RING_IDX rsp_idx;
  61.309 @@ -572,13 +589,13 @@ void dispatch_chmod(struct mount *mount,
  61.310      rsp->ret_val = (uint64_t)ret;
  61.311  }
  61.312  
  61.313 -void dispatch_fs_space(struct mount *mount, struct fsif_request *req)
  61.314 +static void dispatch_fs_space(struct fs_mount *mount, struct fsif_request *req)
  61.315  {
  61.316      char *file_name, full_path[BUFFER_SIZE];
  61.317      RING_IDX rsp_idx;
  61.318      fsif_response_t *rsp;
  61.319      uint16_t req_id;
  61.320 -    struct statfs stat;
  61.321 +    struct statvfs stat;
  61.322      int64_t ret;
  61.323  
  61.324      printf("Dispatching fs space operation (gref=%d).\n", req->u.fspace.gref);
  61.325 @@ -596,7 +613,7 @@ void dispatch_fs_space(struct mount *mou
  61.326             mount->export->export_path, file_name);
  61.327      assert(xc_gnttab_munmap(mount->gnth, file_name, 1) == 0);
  61.328      printf("Issuing fs space for %s\n", full_path);
  61.329 -    ret = statfs(full_path, &stat);
  61.330 +    ret = statvfs(full_path, &stat);
  61.331      if(ret >= 0)
  61.332          ret = stat.f_bsize * stat.f_bfree;
  61.333  
  61.334 @@ -613,7 +630,7 @@ void dispatch_fs_space(struct mount *mou
  61.335      rsp->ret_val = (uint64_t)ret;
  61.336  }
  61.337  
  61.338 -void dispatch_file_sync(struct mount *mount, struct fsif_request *req)
  61.339 +static void dispatch_file_sync(struct fs_mount *mount, struct fsif_request *req)
  61.340  {
  61.341      int fd;
  61.342      uint16_t req_id;
  61.343 @@ -643,7 +660,7 @@ void dispatch_file_sync(struct mount *mo
  61.344      mount->ring.req_cons++;
  61.345  }
  61.346  
  61.347 -void end_file_sync(struct mount *mount, struct fs_request *priv_req)
  61.348 +static void end_file_sync(struct fs_mount *mount, struct fs_request *priv_req)
  61.349  {
  61.350      RING_IDX rsp_idx;
  61.351      fsif_response_t *rsp;
    62.1 --- a/tools/fs-back/fs-xenbus.c	Thu Aug 07 11:47:34 2008 +0900
    62.2 +++ b/tools/fs-back/fs-xenbus.c	Thu Aug 07 11:57:34 2008 +0900
    62.3 @@ -109,10 +109,11 @@ int xenbus_get_watch_fd(void)
    62.4      return xs_fileno(xsh); 
    62.5  }
    62.6  
    62.7 -void xenbus_read_mount_request(struct mount *mount, char *frontend)
    62.8 +void xenbus_read_mount_request(struct fs_mount *mount, char *frontend)
    62.9  {
   62.10      char node[1024];
   62.11      char *s;
   62.12 +    int i;
   62.13  
   62.14      assert(xsh != NULL);
   62.15  #if 0
   62.16 @@ -125,10 +126,18 @@ void xenbus_read_mount_request(struct mo
   62.17      s = xs_read(xsh, XBT_NULL, node, NULL);
   62.18      assert(strcmp(s, STATE_READY) == 0);
   62.19      free(s);
   62.20 -    snprintf(node, sizeof(node), "%s/ring-ref", frontend);
   62.21 +    snprintf(node, sizeof(node), "%s/ring-size", frontend);
   62.22      s = xs_read(xsh, XBT_NULL, node, NULL);
   62.23 -    mount->gref = atoi(s);
   62.24 +    mount->shared_ring_size = atoi(s);
   62.25 +    assert(mount->shared_ring_size <= MAX_RING_SIZE);
   62.26      free(s);
   62.27 +    for(i=0; i<mount->shared_ring_size; i++)
   62.28 +    {
   62.29 +        snprintf(node, sizeof(node), "%s/ring-ref-%d", frontend, i);
   62.30 +        s = xs_read(xsh, XBT_NULL, node, NULL);
   62.31 +        mount->grefs[i] = atoi(s);
   62.32 +        free(s);
   62.33 +    }
   62.34      snprintf(node, sizeof(node), "%s/event-channel", frontend);
   62.35      s = xs_read(xsh, XBT_NULL, node, NULL);
   62.36      mount->remote_evtchn = atoi(s);
   62.37 @@ -150,7 +159,7 @@ static int get_self_id(void)
   62.38  } 
   62.39  
   62.40  
   62.41 -void xenbus_write_backend_node(struct mount *mount)
   62.42 +void xenbus_write_backend_node(struct fs_mount *mount)
   62.43  {
   62.44      char node[1024], backend_node[1024];
   62.45      int self_id;
   62.46 @@ -167,7 +176,7 @@ void xenbus_write_backend_node(struct mo
   62.47      xs_write(xsh, XBT_NULL, node, STATE_INITIALISED, strlen(STATE_INITIALISED));
   62.48  }
   62.49  
   62.50 -void xenbus_write_backend_ready(struct mount *mount)
   62.51 +void xenbus_write_backend_ready(struct fs_mount *mount)
   62.52  {
   62.53      char node[1024];
   62.54      int self_id;
    63.1 --- a/tools/include/xen-sys/MiniOS/privcmd.h	Thu Aug 07 11:47:34 2008 +0900
    63.2 +++ b/tools/include/xen-sys/MiniOS/privcmd.h	Thu Aug 07 11:57:34 2008 +0900
    63.3 @@ -10,9 +10,7 @@ typedef struct privcmd_hypercall
    63.4  } privcmd_hypercall_t;
    63.5  
    63.6  typedef struct privcmd_mmap_entry {
    63.7 -	u64 va;
    63.8  	u64 mfn;
    63.9 -	u64 npages;
   63.10  } privcmd_mmap_entry_t; 
   63.11  
   63.12  #endif /* __MINIOS_PUBLIC_PRIVCMD_H__ */
    64.1 --- a/tools/ioemu/block-vbd.c	Thu Aug 07 11:47:34 2008 +0900
    64.2 +++ b/tools/ioemu/block-vbd.c	Thu Aug 07 11:57:34 2008 +0900
    64.3 @@ -273,6 +273,10 @@ static BlockDriverAIOCB *vbd_aio_flush(B
    64.4      BDRVVbdState *s = bs->opaque;
    64.5      VbdAIOCB *acb = NULL;
    64.6  
    64.7 +    if (s->info.mode == O_RDONLY) {
    64.8 +        cb(opaque, 0);
    64.9 +        return NULL;
   64.10 +    }
   64.11      if (s->info.barrier == 1) {
   64.12          acb = vbd_aio_setup(bs, 0, NULL, 0,
   64.13                  s->info.flush == 1 ? vbd_nop_cb : cb, opaque);
    65.1 --- a/tools/ioemu/hw/pass-through.c	Thu Aug 07 11:47:34 2008 +0900
    65.2 +++ b/tools/ioemu/hw/pass-through.c	Thu Aug 07 11:57:34 2008 +0900
    65.3 @@ -138,6 +138,13 @@ static int pt_msixctrl_reg_write(struct 
    65.4      struct pt_reg_tbl *cfg_entry, 
    65.5      uint16_t *value, uint16_t dev_value, uint16_t valid_mask);
    65.6  
    65.7 +/* pt_reg_info_tbl declaration
    65.8 + * - only for emulated register (either a part or whole bit).
    65.9 + * - for passthrough register that need special behavior (like interacting with
   65.10 + *   other component), set emu_mask to all 0 and specify r/w func properly.
   65.11 + * - do NOT use ALL F for init_val, otherwise the tbl will not be registered.
   65.12 + */
   65.13 + 
   65.14  /* Header Type0 reg static infomation table */
   65.15  static struct pt_reg_info_tbl pt_emu_reg_header0_tbl[] = {
   65.16      /* Command reg */
   65.17 @@ -564,6 +571,13 @@ static struct pt_reg_info_tbl pt_emu_reg
   65.18      }, 
   65.19  };
   65.20  
   65.21 +/* pt_reg_grp_info_tbl declaration
   65.22 + * - only for emulated or zero-hardwired register group.
   65.23 + * - for register group with dynamic size, just set grp_size to 0xFF and 
   65.24 + *   specify size_init func properly.
   65.25 + * - no need to specify emu_reg_tbl for zero-hardwired type.
   65.26 + */
   65.27 +
   65.28  /* emul reg group static infomation table */
   65.29  static const struct pt_reg_grp_info_tbl pt_emu_reg_grp_tbl[] = {
   65.30      /* Header Type0 reg group */
   65.31 @@ -821,7 +835,7 @@ void pt_iomem_map(PCIDevice *d, int i, u
   65.32      assigned_device->bases[i].e_size= e_size;
   65.33  
   65.34      PT_LOG("e_phys=%08x maddr=%lx type=%d len=%d index=%d first_map=%d\n",
   65.35 -        e_phys, assigned_device->bases[i].access.maddr, 
   65.36 +        e_phys, (unsigned long)assigned_device->bases[i].access.maddr, 
   65.37          type, e_size, i, first_map);
   65.38  
   65.39      if ( e_size == 0 )
   65.40 @@ -843,7 +857,7 @@ void pt_iomem_map(PCIDevice *d, int i, u
   65.41          }
   65.42      }
   65.43  
   65.44 -    /* map only valid guest address (include 0) */
   65.45 +    /* map only valid guest address */
   65.46      if (e_phys != -1)
   65.47      {
   65.48          /* Create new mapping */
   65.49 @@ -860,7 +874,7 @@ void pt_iomem_map(PCIDevice *d, int i, u
   65.50          
   65.51          ret = remove_msix_mapping(assigned_device, i);
   65.52          if ( ret != 0 )
   65.53 -            PT_LOG("Error: remove MSX-X mmio mapping failed!\n");
   65.54 +            PT_LOG("Error: remove MSI-X mmio mapping failed!\n");
   65.55      }
   65.56  }
   65.57  
   65.58 @@ -996,8 +1010,11 @@ static void pt_pci_write_config(PCIDevic
   65.59      int index = 0;
   65.60      int ret = 0;
   65.61  
   65.62 -    PT_LOG("write(%x.%x): address=%04x val=0x%08x len=%d\n",
   65.63 -        (d->devfn >> 3) & 0x1F, (d->devfn & 0x7), address, val, len);
   65.64 +#ifdef PT_DEBUG_PCI_CONFIG_ACCESS
   65.65 +    PT_LOG("[%02x:%02x.%x]: address=%04x val=0x%08x len=%d\n",
   65.66 +       pci_bus_num(d->bus), (d->devfn >> 3) & 0x1F, (d->devfn & 0x7),
   65.67 +       address, val, len);
   65.68 +#endif
   65.69  
   65.70      /* check offset range */
   65.71      if (address >= 0xFF)
   65.72 @@ -1049,7 +1066,10 @@ static void pt_pci_write_config(PCIDevic
   65.73          if (reg_grp->grp_type == GRP_TYPE_HARDWIRED)
   65.74          {
   65.75              /* ignore silently */
   65.76 -            PT_LOG("Access to 0 Hardwired register.\n");
   65.77 +            PT_LOG("Access to 0 Hardwired register. "
   65.78 +                "[%02x:%02x.%x][Offset:%02xh][Length:%d]\n",
   65.79 +                pci_bus_num(d->bus), ((d->devfn >> 3) & 0x1F), 
   65.80 +                (d->devfn & 0x7), address, len);
   65.81              goto exit;
   65.82          }
   65.83      }
   65.84 @@ -1067,22 +1087,22 @@ static void pt_pci_write_config(PCIDevic
   65.85          break;
   65.86      }
   65.87  
   65.88 -    /* check libpci error */
   65.89 +    /* check libpci result */
   65.90      valid_mask = (0xFFFFFFFF >> ((4 - len) << 3));
   65.91      if ((read_val & valid_mask) == valid_mask)
   65.92      {
   65.93 -        PT_LOG("libpci read error. No emulation. "
   65.94 +        PT_LOG("Warning: Return ALL F from libpci read. "
   65.95              "[%02x:%02x.%x][Offset:%02xh][Length:%d]\n",
   65.96              pci_bus_num(d->bus), ((d->devfn >> 3) & 0x1F), (d->devfn & 0x7),
   65.97              address, len);
   65.98 -        goto exit;
   65.99      }
  65.100      
  65.101      /* pass directly to libpci for passthrough type register group */
  65.102      if (reg_grp_entry == NULL)
  65.103          goto out;
  65.104  
  65.105 -    /* adjust the write value to appropriate CFC-CFF window */
  65.106 +    /* adjust the read and write value to appropriate CFC-CFF window */
  65.107 +    read_val <<= ((address & 3) << 3);
  65.108      val <<= ((address & 3) << 3);
  65.109      emul_len = len;
  65.110  
  65.111 @@ -1131,7 +1151,8 @@ static void pt_pci_write_config(PCIDevic
  65.112              if (ret < 0)
  65.113              {
  65.114                  /* exit I/O emulator */
  65.115 -                PT_LOG("I/O emulator exit()\n");
  65.116 +                PT_LOG("Internal error: Invalid write emulation "
  65.117 +                    "return value[%d]. I/O emulator exit.\n", ret);
  65.118                  exit(1);
  65.119              }
  65.120  
  65.121 @@ -1186,9 +1207,6 @@ static uint32_t pt_pci_read_config(PCIDe
  65.122      int emul_len = 0;
  65.123      int ret = 0;
  65.124  
  65.125 -    PT_LOG("read(%x.%x): address=%04x len=%d\n",
  65.126 -        (d->devfn >> 3) & 0x1F, (d->devfn & 0x7), address, len);
  65.127 -
  65.128      /* check offset range */
  65.129      if (address >= 0xFF)
  65.130      {
  65.131 @@ -1246,15 +1264,14 @@ static uint32_t pt_pci_read_config(PCIDe
  65.132          break;
  65.133      }
  65.134  
  65.135 -    /* check libpci error */
  65.136 +    /* check libpci result */
  65.137      valid_mask = (0xFFFFFFFF >> ((4 - len) << 3));
  65.138      if ((val & valid_mask) == valid_mask)
  65.139      {
  65.140 -        PT_LOG("libpci read error. No emulation. "
  65.141 +        PT_LOG("Warning: Return ALL F from libpci read. "
  65.142              "[%02x:%02x.%x][Offset:%02xh][Length:%d]\n",
  65.143              pci_bus_num(d->bus), ((d->devfn >> 3) & 0x1F), (d->devfn & 0x7),
  65.144              address, len);
  65.145 -        goto exit;
  65.146      }
  65.147  
  65.148      /* just return the I/O device register value for 
  65.149 @@ -1309,7 +1326,8 @@ static uint32_t pt_pci_read_config(PCIDe
  65.150              if (ret < 0)
  65.151              {
  65.152                  /* exit I/O emulator */
  65.153 -                PT_LOG("I/O emulator exit()\n");
  65.154 +                PT_LOG("Internal error: Invalid read emulation "
  65.155 +                    "return value[%d]. I/O emulator exit.\n", ret);
  65.156                  exit(1);
  65.157              }
  65.158  
  65.159 @@ -1332,6 +1350,13 @@ static uint32_t pt_pci_read_config(PCIDe
  65.160      val >>= ((address & 3) << 3);
  65.161  
  65.162  exit:
  65.163 +
  65.164 +#ifdef PT_DEBUG_PCI_CONFIG_ACCESS
  65.165 +    PT_LOG("[%02x:%02x.%x]: address=%04x val=0x%08x len=%d\n",
  65.166 +       pci_bus_num(d->bus), (d->devfn >> 3) & 0x1F, (d->devfn & 0x7),
  65.167 +       address, val, len);
  65.168 +#endif
  65.169 +
  65.170      return val;
  65.171  }
  65.172  
  65.173 @@ -1389,7 +1414,7 @@ static int pt_register_regions(struct pt
  65.174      return 0;
  65.175  }
  65.176  
  65.177 -static int pt_unregister_regions(struct pt_dev *assigned_device)
  65.178 +static void pt_unregister_regions(struct pt_dev *assigned_device)
  65.179  {
  65.180      int i, type, ret;
  65.181      uint32_t e_size;
  65.182 @@ -1488,7 +1513,9 @@ static int pt_bar_reg_parse(
  65.183      /* check 64bit BAR */
  65.184      index = pt_bar_offset_to_index(reg->offset);
  65.185      if ((index > 0) && (index < PCI_ROM_SLOT) &&
  65.186 -        (d->config[bar_64] & PCI_BASE_ADDRESS_MEM_TYPE_64))
  65.187 +        ((d->config[bar_64] & (PCI_BASE_ADDRESS_SPACE |
  65.188 +                               PCI_BASE_ADDRESS_MEM_TYPE_MASK)) ==
  65.189 +         (PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64)))
  65.190      {
  65.191          region = &ptdev->bases[index-1];
  65.192          if (region->bar_flag != PT_BAR_FLAG_UPPER)
  65.193 @@ -1503,6 +1530,13 @@ static int pt_bar_reg_parse(
  65.194      if (!r->size)
  65.195          goto out;
  65.196  
  65.197 +    /* for ExpROM BAR */
  65.198 +    if (index == PCI_ROM_SLOT)
  65.199 +    {
  65.200 +        bar_flag = PT_BAR_FLAG_MEM;
  65.201 +        goto out;
  65.202 +    }
  65.203 +
  65.204      /* check BAR I/O indicator */
  65.205      if (d->config[reg->offset] & PCI_BASE_ADDRESS_SPACE_IO)
  65.206          bar_flag = PT_BAR_FLAG_IO;
  65.207 @@ -1540,7 +1574,7 @@ static void pt_bar_mapping(struct pt_dev
  65.208          /* copy region address to temporary */
  65.209          r_addr = r->addr;
  65.210  
  65.211 -        /* clear region address in case I/O Space or Memory Space disable */
  65.212 +        /* need unmapping in case I/O Space or Memory Space disable */
  65.213          if (((base->bar_flag == PT_BAR_FLAG_IO) && !io_enable ) ||
  65.214              ((base->bar_flag == PT_BAR_FLAG_MEM) && !mem_enable ))
  65.215              r_addr = -1;
  65.216 @@ -1556,8 +1590,10 @@ static void pt_bar_mapping(struct pt_dev
  65.217          /* check overlapped address */
  65.218          ret = pt_chk_bar_overlap(dev->bus, dev->devfn, r_addr, r_size);
  65.219          if (ret > 0)
  65.220 -            PT_LOG("Base Address[%d] is overlapped. "
  65.221 -                "[Address:%08xh][Size:%04xh]\n", i, r_addr, r_size);
  65.222 +            PT_LOG("ptdev[%02x:%02x.%x][Region:%d][Address:%08xh][Size:%08xh] "
  65.223 +                "is overlapped.\n", pci_bus_num(dev->bus), 
  65.224 +                (dev->devfn >> 3) & 0x1F, (dev->devfn & 0x7),
  65.225 +                i, r_addr, r_size);
  65.226  
  65.227          /* check whether we need to update the mapping or not */
  65.228          if (r_addr != ptdev->bases[i].e_physbase)
  65.229 @@ -1776,14 +1812,16 @@ static uint32_t pt_status_reg_init(struc
  65.230          else
  65.231          {
  65.232              /* exit I/O emulator */
  65.233 -            PT_LOG("I/O emulator exit()\n");
  65.234 +            PT_LOG("Internal error: Couldn't find pt_reg_tbl for "
  65.235 +                "Capabilities Pointer register. I/O emulator exit.\n");
  65.236              exit(1);
  65.237          }
  65.238      }
  65.239      else
  65.240      {
  65.241          /* exit I/O emulator */
  65.242 -        PT_LOG("I/O emulator exit()\n");
  65.243 +        PT_LOG("Internal error: Couldn't find pt_reg_grp_tbl for Header. "
  65.244 +            "I/O emulator exit.\n");
  65.245          exit(1);
  65.246      }
  65.247  
  65.248 @@ -1815,7 +1853,8 @@ static uint32_t pt_bar_reg_init(struct p
  65.249      if (index < 0)
  65.250      {
  65.251          /* exit I/O emulator */
  65.252 -        PT_LOG("I/O emulator exit()\n");
  65.253 +        PT_LOG("Internal error: Invalid BAR index[%d]. "
  65.254 +            "I/O emulator exit.\n", index);
  65.255          exit(1);
  65.256      }
  65.257  
  65.258 @@ -1962,9 +2001,8 @@ static uint8_t pt_msi_size_init(struct p
  65.259      ptdev->msi = malloc(sizeof(struct pt_msi_info));
  65.260      if ( !ptdev->msi )
  65.261      {
  65.262 -        PT_LOG("error allocation pt_msi_info\n");
  65.263          /* exit I/O emulator */
  65.264 -        PT_LOG("I/O emulator exit()\n");
  65.265 +        PT_LOG("error allocation pt_msi_info. I/O emulator exit.\n");
  65.266          exit(1);
  65.267      }
  65.268      memset(ptdev->msi, 0, sizeof(struct pt_msi_info));
  65.269 @@ -1983,7 +2021,8 @@ static uint8_t pt_msix_size_init(struct 
  65.270      if (ret == -1)
  65.271      {
  65.272          /* exit I/O emulator */
  65.273 -        PT_LOG("I/O emulator exit()\n");
  65.274 +        PT_LOG("Internal error: Invalid pt_msix_init return value[%d]. "
  65.275 +            "I/O emulator exit.\n", ret);
  65.276          exit(1);
  65.277      }
  65.278  
  65.279 @@ -2060,7 +2099,8 @@ static int pt_bar_reg_read(struct pt_dev
  65.280      if (index < 0)
  65.281      {
  65.282          /* exit I/O emulator */
  65.283 -        PT_LOG("I/O emulator exit()\n");
  65.284 +        PT_LOG("Internal error: Invalid BAR index[%d]. "
  65.285 +            "I/O emulator exit.\n", index);
  65.286          exit(1);
  65.287      }
  65.288  
  65.289 @@ -2074,8 +2114,8 @@ static int pt_bar_reg_read(struct pt_dev
  65.290          bar_emu_mask = PT_BAR_IO_EMU_MASK;
  65.291          break;
  65.292      case PT_BAR_FLAG_UPPER:
  65.293 -        *value = 0;
  65.294 -        goto out;
  65.295 +        bar_emu_mask = PT_BAR_ALLF;
  65.296 +        break;
  65.297      default:
  65.298          break;
  65.299      }
  65.300 @@ -2085,7 +2125,6 @@ static int pt_bar_reg_read(struct pt_dev
  65.301      *value = ((*value & ~valid_emu_mask) | 
  65.302                (cfg_entry->data & valid_emu_mask));
  65.303  
  65.304 -out:
  65.305     return 0;
  65.306  }
  65.307  
  65.308 @@ -2201,12 +2240,13 @@ static int pt_bar_reg_write(struct pt_de
  65.309      uint32_t r_size = 0;
  65.310      int index = 0;
  65.311  
  65.312 -   /* get BAR index */
  65.313 +    /* get BAR index */
  65.314      index = pt_bar_offset_to_index(reg->offset);
  65.315      if (index < 0)
  65.316      {
  65.317          /* exit I/O emulator */
  65.318 -        PT_LOG("I/O emulator exit()\n");
  65.319 +        PT_LOG("Internal error: Invalid BAR index[%d]. "
  65.320 +            "I/O emulator exit.\n", index);
  65.321          exit(1);
  65.322      }
  65.323  
  65.324 @@ -2216,89 +2256,113 @@ static int pt_bar_reg_write(struct pt_de
  65.325      /* align resource size (memory type only) */
  65.326      PT_GET_EMUL_SIZE(base->bar_flag, r_size);
  65.327  
  65.328 -    /* check guest write value */
  65.329 -    if (*value == PT_BAR_ALLF)
  65.330 -    {
  65.331 -        /* set register with resource size alligned to page size */
  65.332 -        cfg_entry->data = ~(r_size - 1);
  65.333 -        /* avoid writing ALL F to I/O device register */
  65.334 -        *value = dev_value;
  65.335 -    }
  65.336 -    else
  65.337 +    /* set emulate mask and read-only mask depend on BAR flag */
  65.338 +    switch (ptdev->bases[index].bar_flag)
  65.339      {
  65.340 -        /* set emulate mask and read-only mask depend on BAR flag */
  65.341 -        switch (ptdev->bases[index].bar_flag)
  65.342 +    case PT_BAR_FLAG_MEM:
  65.343 +        bar_emu_mask = PT_BAR_MEM_EMU_MASK;
  65.344 +        bar_ro_mask = PT_BAR_MEM_RO_MASK | (r_size - 1);
  65.345 +        break;
  65.346 +    case PT_BAR_FLAG_IO:
  65.347 +        bar_emu_mask = PT_BAR_IO_EMU_MASK;
  65.348 +        bar_ro_mask = PT_BAR_IO_RO_MASK | (r_size - 1);
  65.349 +        break;
  65.350 +    case PT_BAR_FLAG_UPPER:
  65.351 +        bar_emu_mask = PT_BAR_ALLF;
  65.352 +        bar_ro_mask = 0;    /* all upper 32bit are R/W */
  65.353 +        break;
  65.354 +    default:
  65.355 +        break;
  65.356 +    }
  65.357 +
  65.358 +    /* modify emulate register */
  65.359 +    writable_mask = bar_emu_mask & ~bar_ro_mask & valid_mask;
  65.360 +    cfg_entry->data = ((*value & writable_mask) |
  65.361 +                       (cfg_entry->data & ~writable_mask));
  65.362 +
  65.363 +    /* check whether we need to update the virtual region address or not */
  65.364 +    switch (ptdev->bases[index].bar_flag)
  65.365 +    {
  65.366 +    case PT_BAR_FLAG_MEM:
  65.367 +        /* nothing to do */
  65.368 +        break;
  65.369 +    case PT_BAR_FLAG_IO:
  65.370 +        new_addr = cfg_entry->data;
  65.371 +        last_addr = new_addr + r_size - 1;
  65.372 +        /* check invalid address */
  65.373 +        if (last_addr <= new_addr || !new_addr || last_addr >= 0x10000)
  65.374          {
  65.375 -        case PT_BAR_FLAG_MEM:
  65.376 -            bar_emu_mask = PT_BAR_MEM_EMU_MASK;
  65.377 -            bar_ro_mask = PT_BAR_MEM_RO_MASK;
  65.378 -            break;
  65.379 -        case PT_BAR_FLAG_IO:
  65.380 -            new_addr = *value;
  65.381 -            last_addr = new_addr + r_size - 1;
  65.382              /* check 64K range */
  65.383 -            if (last_addr <= new_addr || !new_addr || last_addr >= 0x10000)
  65.384 +            if ((last_addr >= 0x10000) &&
  65.385 +                (cfg_entry->data != (PT_BAR_ALLF & ~bar_ro_mask)))
  65.386              {
  65.387                  PT_LOG("Guest attempt to set Base Address over the 64KB. "
  65.388 -                    "[%02x:%02x.%x][Offset:%02xh][Range:%08xh-%08xh]\n",
  65.389 +                    "[%02x:%02x.%x][Offset:%02xh][Address:%08xh][Size:%08xh]\n",
  65.390                      pci_bus_num(d->bus), 
  65.391                      ((d->devfn >> 3) & 0x1F), (d->devfn & 0x7),
  65.392 -                    reg->offset, new_addr, last_addr);
  65.393 -                /* just remove mapping */
  65.394 -                r->addr = -1;
  65.395 -                goto exit;
  65.396 +                    reg->offset, new_addr, r_size);
  65.397              }
  65.398 -            bar_emu_mask = PT_BAR_IO_EMU_MASK;
  65.399 -            bar_ro_mask = PT_BAR_IO_RO_MASK;
  65.400 -            break;
  65.401 -        case PT_BAR_FLAG_UPPER:
  65.402 -            if (*value)
  65.403 +            /* just remove mapping */
  65.404 +            r->addr = -1;
  65.405 +            goto exit;
  65.406 +        }
  65.407 +        break;
  65.408 +    case PT_BAR_FLAG_UPPER:
  65.409 +        if (cfg_entry->data)
  65.410 +        {
  65.411 +            if (cfg_entry->data != (PT_BAR_ALLF & ~bar_ro_mask))
  65.412              {
  65.413                  PT_LOG("Guest attempt to set high MMIO Base Address. "
  65.414 -                   "Ignore mapping. "
  65.415 -                   "[%02x:%02x.%x][Offset:%02xh][High Address:%08xh]\n",
  65.416 +                    "Ignore mapping. "
  65.417 +                    "[%02x:%02x.%x][Offset:%02xh][High Address:%08xh]\n",
  65.418                      pci_bus_num(d->bus), 
  65.419                      ((d->devfn >> 3) & 0x1F), (d->devfn & 0x7),
  65.420 -                    reg->offset, *value);
  65.421 -                /* clear lower address */
  65.422 -                d->io_regions[index-1].addr = -1;
  65.423 +                    reg->offset, cfg_entry->data);
  65.424              }
  65.425 -            else
  65.426 +            /* clear lower address */
  65.427 +            d->io_regions[index-1].addr = -1;
  65.428 +        }
  65.429 +        else
  65.430 +        {
  65.431 +            /* find lower 32bit BAR */
  65.432 +            prev_offset = (reg->offset - 4);
  65.433 +            reg_grp_entry = pt_find_reg_grp(ptdev, prev_offset);
  65.434 +            if (reg_grp_entry)
  65.435              {
  65.436 -                /* find lower 32bit BAR */
  65.437 -                prev_offset = (reg->offset - 4);
  65.438 -                reg_grp_entry = pt_find_reg_grp(ptdev, prev_offset);
  65.439 -                if (reg_grp_entry)
  65.440 -                {
  65.441 -                    reg_entry = pt_find_reg(reg_grp_entry, prev_offset);
  65.442 -                    if (reg_entry)
  65.443 -                        /* restore lower address */
  65.444 -                        d->io_regions[index-1].addr = reg_entry->data;
  65.445 -                    else
  65.446 -                        return -1;
  65.447 -                }
  65.448 +                reg_entry = pt_find_reg(reg_grp_entry, prev_offset);
  65.449 +                if (reg_entry)
  65.450 +                    /* restore lower address */
  65.451 +                    d->io_regions[index-1].addr = reg_entry->data;
  65.452                  else
  65.453                      return -1;
  65.454              }
  65.455 -            cfg_entry->data = 0;
  65.456 -            r->addr = -1;
  65.457 -            goto exit;
  65.458 +            else
  65.459 +                return -1;
  65.460          }
  65.461  
  65.462 -        /* modify emulate register */
  65.463 -        writable_mask = bar_emu_mask & ~bar_ro_mask & valid_mask;
  65.464 -        cfg_entry->data = ((*value & writable_mask) |
  65.465 -                           (cfg_entry->data & ~writable_mask));
  65.466 -        /* update the corresponding virtual region address */
  65.467 -        r->addr = cfg_entry->data;
  65.468 -
  65.469 -        /* create value for writing to I/O device register */
  65.470 -        throughable_mask = ~bar_emu_mask & valid_mask;
  65.471 -        *value = ((*value & throughable_mask) |
  65.472 -                  (dev_value & ~throughable_mask));
  65.473 +        /* always keep the emulate register value to 0,
  65.474 +         * because hvmloader does not support high MMIO for now.
  65.475 +         */
  65.476 +        cfg_entry->data = 0;
  65.477 +
  65.478 +        /* never mapping the 'empty' upper region,
  65.479 +         * because we'll do it enough for the lower region.
  65.480 +         */
  65.481 +        r->addr = -1;
  65.482 +        goto exit;
  65.483 +    default:
  65.484 +        break;
  65.485      }
  65.486  
  65.487 +    /* update the corresponding virtual region address */
  65.488 +    r->addr = cfg_entry->data;
  65.489 +
  65.490  exit:
  65.491 +    /* create value for writing to I/O device register */
  65.492 +    throughable_mask = ~bar_emu_mask & valid_mask;
  65.493 +    *value = ((*value & throughable_mask) |
  65.494 +              (dev_value & ~throughable_mask));
  65.495 +
  65.496      return 0;
  65.497  }
  65.498  
  65.499 @@ -2314,6 +2378,8 @@ static int pt_exp_rom_bar_reg_write(stru
  65.500      uint32_t writable_mask = 0;
  65.501      uint32_t throughable_mask = 0;
  65.502      uint32_t r_size = 0;
  65.503 +    uint32_t bar_emu_mask = 0;
  65.504 +    uint32_t bar_ro_mask = 0;
  65.505  
  65.506      r = &d->io_regions[PCI_ROM_SLOT];
  65.507      r_size = r->size;
  65.508 @@ -2321,28 +2387,22 @@ static int pt_exp_rom_bar_reg_write(stru
  65.509      /* align memory type resource size */
  65.510      PT_GET_EMUL_SIZE(base->bar_flag, r_size);
  65.511  
  65.512 -    /* check guest write value */
  65.513 -    if (*value == PT_BAR_ALLF)
  65.514 -    {
  65.515 -        /* set register with resource size alligned to page size */
  65.516 -        cfg_entry->data = ~(r_size - 1);
  65.517 -        /* avoid writing ALL F to I/O device register */
  65.518 -        *value = dev_value;
  65.519 -    }
  65.520 -    else
  65.521 -    {
  65.522 -        /* modify emulate register */
  65.523 -        writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
  65.524 -        cfg_entry->data = ((*value & writable_mask) |
  65.525 -                           (cfg_entry->data & ~writable_mask));
  65.526 -        /* update the corresponding virtual region address */
  65.527 -        r->addr = cfg_entry->data;
  65.528 -
  65.529 -        /* create value for writing to I/O device register */
  65.530 -        throughable_mask = ~reg->emu_mask & valid_mask;
  65.531 -        *value = ((*value & throughable_mask) |
  65.532 -                  (dev_value & ~throughable_mask));
  65.533 -    }
  65.534 +    /* set emulate mask and read-only mask */
  65.535 +    bar_emu_mask = reg->emu_mask;
  65.536 +    bar_ro_mask = reg->ro_mask | (r_size - 1);
  65.537 +
  65.538 +    /* modify emulate register */
  65.539 +    writable_mask = bar_emu_mask & ~bar_ro_mask & valid_mask;
  65.540 +    cfg_entry->data = ((*value & writable_mask) |
  65.541 +                       (cfg_entry->data & ~writable_mask));
  65.542 +
  65.543 +    /* update the corresponding virtual region address */
  65.544 +    r->addr = cfg_entry->data;
  65.545 +    
  65.546 +    /* create value for writing to I/O device register */
  65.547 +    throughable_mask = ~bar_emu_mask & valid_mask;
  65.548 +    *value = ((*value & throughable_mask) |
  65.549 +              (dev_value & ~throughable_mask));
  65.550  
  65.551      return 0;
  65.552  }
  65.553 @@ -2484,8 +2544,6 @@ static int pt_msgctrl_reg_write(struct p
  65.554      uint16_t old_ctrl = cfg_entry->data;
  65.555      PCIDevice *pd = (PCIDevice *)ptdev;
  65.556  
  65.557 -    PT_LOG("[before] dev_val:%xh wr_val:%xh\n", dev_value, *value);
  65.558 -
  65.559      /* Currently no support for multi-vector */
  65.560      if ((*value & PCI_MSI_FLAGS_QSIZE) != 0x0)
  65.561          PT_LOG("try to set more than 1 vector ctrl %x\n", *value);
  65.562 @@ -2527,8 +2585,6 @@ static int pt_msgctrl_reg_write(struct p
  65.563      else
  65.564          ptdev->msi->flags &= ~PCI_MSI_FLAGS_ENABLE;
  65.565  
  65.566 -    PT_LOG("[after] wr_val:%xh\n", *value);
  65.567 -
  65.568      return 0;
  65.569  }
  65.570  
  65.571 @@ -2542,8 +2598,6 @@ static int pt_msgaddr32_reg_write(struct
  65.572      uint32_t throughable_mask = 0;
  65.573      uint32_t old_addr = cfg_entry->data;
  65.574  
  65.575 -    PT_LOG("[before] dev_val:%xh wr_val:%xh\n", dev_value, *value);
  65.576 -
  65.577      /* modify emulate register */
  65.578      writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
  65.579      cfg_entry->data = ((*value & writable_mask) |
  65.580 @@ -2564,8 +2618,6 @@ static int pt_msgaddr32_reg_write(struct
  65.581              pt_msi_update(ptdev);
  65.582      }
  65.583  
  65.584 -    PT_LOG("[after] wr_val:%xh\n", *value);
  65.585 -
  65.586      return 0;
  65.587  }
  65.588  
  65.589 @@ -2579,8 +2631,6 @@ static int pt_msgaddr64_reg_write(struct
  65.590      uint32_t throughable_mask = 0;
  65.591      uint32_t old_addr = cfg_entry->data;
  65.592  
  65.593 -    PT_LOG("[before] dev_val:%xh wr_val:%xh\n", dev_value, *value);
  65.594 -
  65.595      /* check whether the type is 64 bit or not */
  65.596      if (!(ptdev->msi->flags & PCI_MSI_FLAGS_64BIT))
  65.597      {
  65.598 @@ -2609,8 +2659,6 @@ static int pt_msgaddr64_reg_write(struct
  65.599              pt_msi_update(ptdev);
  65.600      }
  65.601  
  65.602 -    PT_LOG("[after] wr_val:%xh\n", *value);
  65.603 -
  65.604      return 0;
  65.605  }
  65.606  
  65.607 @@ -2627,8 +2675,6 @@ static int pt_msgdata_reg_write(struct p
  65.608      uint32_t flags = ptdev->msi->flags;
  65.609      uint32_t offset = reg->offset;
  65.610  
  65.611 -    PT_LOG("[before] dev_val:%xh wr_val:%xh\n", dev_value, *value);
  65.612 -
  65.613      /* check the offset whether matches the type or not */
  65.614      if (!((offset == PCI_MSI_DATA_64) &&  (flags & PCI_MSI_FLAGS_64BIT)) &&
  65.615          !((offset == PCI_MSI_DATA_32) && !(flags & PCI_MSI_FLAGS_64BIT)))
  65.616 @@ -2658,8 +2704,6 @@ static int pt_msgdata_reg_write(struct p
  65.617              pt_msi_update(ptdev);
  65.618      }
  65.619  
  65.620 -    PT_LOG("[after] wr_val:%xh\n", *value);
  65.621 -
  65.622      return 0;
  65.623  }
  65.624  
  65.625 @@ -2673,8 +2717,6 @@ static int pt_msixctrl_reg_write(struct 
  65.626      uint16_t throughable_mask = 0;
  65.627      uint16_t old_ctrl = cfg_entry->data;
  65.628  
  65.629 -    PT_LOG("[before] dev_val:%xh wr_val:%xh\n", dev_value, *value);
  65.630 -
  65.631      /* modify emulate register */
  65.632      writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
  65.633      cfg_entry->data = ((*value & writable_mask) |
  65.634 @@ -2692,8 +2734,6 @@ static int pt_msixctrl_reg_write(struct 
  65.635  
  65.636      ptdev->msix->enabled = !!(*value & PCI_MSIX_ENABLE);
  65.637  
  65.638 -    PT_LOG("[after] wr_val:%xh\n", *value);
  65.639 -
  65.640      return 0;
  65.641  }
  65.642  
  65.643 @@ -2785,8 +2825,7 @@ struct pt_dev * register_real_device(PCI
  65.644          int pirq = pci_dev->irq;
  65.645  
  65.646          machine_irq = pci_dev->irq;
  65.647 -        rc = xc_physdev_map_pirq(xc_handle, domid, MAP_PIRQ_TYPE_GSI,
  65.648 -                                machine_irq, &pirq);
  65.649 +        rc = xc_physdev_map_pirq(xc_handle, domid, machine_irq, &pirq);
  65.650  
  65.651          if ( rc )
  65.652          {
    66.1 --- a/tools/ioemu/hw/pass-through.h	Thu Aug 07 11:47:34 2008 +0900
    66.2 +++ b/tools/ioemu/hw/pass-through.h	Thu Aug 07 11:57:34 2008 +0900
    66.3 @@ -47,12 +47,20 @@
    66.4  /* because the current version of libpci (2.2.0) doesn't define these ID,
    66.5   * so we define Capability ID here.
    66.6   */
    66.7 +#ifndef PCI_CAP_ID_HOTPLUG
    66.8  /* SHPC Capability List Item reg group */
    66.9  #define PCI_CAP_ID_HOTPLUG      0x0C
   66.10 +#endif
   66.11 +
   66.12 +#ifndef PCI_CAP_ID_SSVID
   66.13  /* Subsystem ID and Subsystem Vendor ID Capability List Item reg group */
   66.14  #define PCI_CAP_ID_SSVID        0x0D
   66.15 +#endif
   66.16 +
   66.17 +#ifndef PCI_MSI_FLAGS_MASK_BIT
   66.18  /* interrupt masking & reporting supported */
   66.19  #define PCI_MSI_FLAGS_MASK_BIT  0x0100
   66.20 +#endif
   66.21  
   66.22  #define PT_INVALID_REG          0xFFFFFFFF      /* invalid register value */
   66.23  #define PT_BAR_ALLF             0xFFFFFFFF      /* BAR ALLF value */
    67.1 --- a/tools/ioemu/hw/pc.c	Thu Aug 07 11:47:34 2008 +0900
    67.2 +++ b/tools/ioemu/hw/pc.c	Thu Aug 07 11:57:34 2008 +0900
    67.3 @@ -31,9 +31,6 @@
    67.4  #define VGABIOS_CIRRUS_FILENAME "vgabios-cirrus.bin"
    67.5  #define LINUX_BOOT_FILENAME "linux_boot.bin"
    67.6  
    67.7 -/* Leave a chunk of memory at the top of RAM for the BIOS ACPI tables.  */
    67.8 -#define ACPI_DATA_SIZE        0x10000
    67.9 -
   67.10  static fdctrl_t *floppy_controller;
   67.11  static RTCState *rtc_state;
   67.12  #ifndef CONFIG_DM
   67.13 @@ -542,6 +539,7 @@ static void load_linux(const char *kerne
   67.14      uint16_t seg[6];
   67.15      uint16_t real_seg;
   67.16      int setup_size, kernel_size, initrd_size, cmdline_size;
   67.17 +    unsigned long end_low_ram;
   67.18      uint32_t initrd_max;
   67.19      uint8_t header[1024];
   67.20      target_phys_addr_t real_addr, reloc_prot_addr, prot_addr, cmdline_addr, initrd_addr;
   67.21 @@ -595,15 +593,14 @@ static void load_linux(const char *kerne
   67.22              (size_t)cmdline_addr,
   67.23              (size_t)prot_addr);
   67.24  
   67.25 +    /* Special pages are placed at end of low RAM: pick an arbitrary one and
   67.26 +     * subtract a suitably large amount of padding (64kB) to skip BIOS data. */
   67.27 +    xc_get_hvm_param(xc_handle, domid, HVM_PARAM_BUFIOREQ_PFN, &end_low_ram);
   67.28 +    end_low_ram = (end_low_ram << 12) - (64*1024);
   67.29 +
   67.30      /* highest address for loading the initrd */
   67.31 -    if (protocol >= 0x203)
   67.32 -        initrd_max = ldl_p(header+0x22c);
   67.33 -    else
   67.34 -        initrd_max = 0x37ffffff;
   67.35 -
   67.36 -    if (initrd_max >= ram_size-ACPI_DATA_SIZE)
   67.37 -        initrd_max = ram_size-ACPI_DATA_SIZE-1;
   67.38 -
   67.39 +    initrd_max = (protocol >= 0x203) ? ldl_p(header+0x22c) : 0x37ffffff;
   67.40 +    initrd_max = MIN(initrd_max, (uint32_t)end_low_ram);
   67.41  
   67.42      /* kernel command line */
   67.43      ncmdline = strlen(kernel_cmdline);
    68.1 --- a/tools/ioemu/hw/pci.c	Thu Aug 07 11:47:34 2008 +0900
    68.2 +++ b/tools/ioemu/hw/pci.c	Thu Aug 07 11:57:34 2008 +0900
    68.3 @@ -664,9 +664,10 @@ int pt_chk_bar_overlap(PCIBus *bus, int 
    68.4              r = &devices->io_regions[j];
    68.5              if ((addr < (r->addr + r->size)) && ((addr + size) > r->addr))
    68.6              {
    68.7 -                printf("Overlapped to device[%02x:%02x.%x] region:%d addr:%08x"
    68.8 -                    " size:%08x\n", bus->bus_num, (devices->devfn >> 3) & 0x1F,
    68.9 -                    (devices->devfn & 0x7), j, r->addr, r->size);
   68.10 +                printf("Overlapped to device[%02x:%02x.%x][Region:%d]"
   68.11 +                    "[Address:%08xh][Size:%08xh]\n", bus->bus_num,
   68.12 +                    (devices->devfn >> 3) & 0x1F, (devices->devfn & 0x7),
   68.13 +                    j, r->addr, r->size);
   68.14                  ret = 1;
   68.15                  goto out;
   68.16              }
    69.1 --- a/tools/ioemu/hw/pt-msi.c	Thu Aug 07 11:47:34 2008 +0900
    69.2 +++ b/tools/ioemu/hw/pt-msi.c	Thu Aug 07 11:57:34 2008 +0900
    69.3 @@ -37,8 +37,7 @@ int pt_msi_setup(struct pt_dev *dev)
    69.4          return -1;
    69.5      }
    69.6  
    69.7 -    if ( xc_physdev_map_pirq_msi(xc_handle, domid, MAP_PIRQ_TYPE_MSI,
    69.8 -                            AUTO_ASSIGN, &pirq,
    69.9 +    if ( xc_physdev_map_pirq_msi(xc_handle, domid, AUTO_ASSIGN, &pirq,
   69.10  							dev->pci_dev->dev << 3 | dev->pci_dev->func,
   69.11  							dev->pci_dev->bus, 0, 1) )
   69.12      {
   69.13 @@ -120,8 +119,7 @@ static int pt_msix_update_one(struct pt_
   69.14      /* Check if this entry is already mapped */
   69.15      if ( entry->pirq == -1 )
   69.16      {
   69.17 -        ret = xc_physdev_map_pirq_msi(xc_handle, domid, MAP_PIRQ_TYPE_MSI,
   69.18 -                                AUTO_ASSIGN, &pirq,
   69.19 +        ret = xc_physdev_map_pirq_msi(xc_handle, domid, AUTO_ASSIGN, &pirq,
   69.20                                  dev->pci_dev->dev << 3 | dev->pci_dev->func,
   69.21                                  dev->pci_dev->bus, entry_nr, 0);
   69.22          if ( ret )
    70.1 --- a/tools/ioemu/hw/serial.c	Thu Aug 07 11:47:34 2008 +0900
    70.2 +++ b/tools/ioemu/hw/serial.c	Thu Aug 07 11:57:34 2008 +0900
    70.3 @@ -728,7 +728,6 @@ static int serial_load(QEMUFile *f, void
    70.4      qemu_get_8s(f,&s->lsr);
    70.5      qemu_get_8s(f,&s->msr);
    70.6      qemu_get_8s(f,&s->scr);
    70.7 -    qemu_get_8s(f,&s->fcr);
    70.8  
    70.9      if (version_id >= 2)
   70.10          qemu_get_8s(f,&fcr);
    71.1 --- a/tools/ioemu/hw/vga.c	Thu Aug 07 11:47:34 2008 +0900
    71.2 +++ b/tools/ioemu/hw/vga.c	Thu Aug 07 11:57:34 2008 +0900
    71.3 @@ -1548,8 +1548,8 @@ static void vga_draw_graphic(VGAState *s
    71.4              } else {
    71.5                  /* ENODATA just means we have changed mode and will succeed
    71.6                   * next time */
    71.7 -                if (err != -ENODATA)
    71.8 -                    fprintf(stderr, "track_dirty_vram(%lx, %lx) failed (%d)\n", s->lfb_addr + y, npages, err);
    71.9 +                if (errno != ENODATA)
   71.10 +                    fprintf(stderr, "track_dirty_vram(%lx, %lx) failed (%d, %d)\n", s->lfb_addr + y, npages, err, errno);
   71.11              }
   71.12          }
   71.13  
    72.1 --- a/tools/ioemu/vl.c	Thu Aug 07 11:47:34 2008 +0900
    72.2 +++ b/tools/ioemu/vl.c	Thu Aug 07 11:57:34 2008 +0900
    72.3 @@ -7136,8 +7136,10 @@ int main(int argc, char **argv)
    72.4          sigaddset(&set, aio_sig_num);
    72.5          sigprocmask(SIG_BLOCK, &set, NULL);
    72.6      }
    72.7 +#endif
    72.8  
    72.9      QEMU_LIST_INIT (&vm_change_state_head);
   72.10 +#ifndef CONFIG_STUBDOM
   72.11  #ifndef _WIN32
   72.12      {
   72.13          struct sigaction act;
    73.1 --- a/tools/libaio/src/Makefile	Thu Aug 07 11:47:34 2008 +0900
    73.2 +++ b/tools/libaio/src/Makefile	Thu Aug 07 11:57:34 2008 +0900
    73.3 @@ -1,7 +1,7 @@
    73.4  XEN_ROOT = ../../..
    73.5  include $(XEN_ROOT)/tools/Rules.mk
    73.6  
    73.7 -prefix=/usr
    73.8 +prefix=$(PREFIX)
    73.9  includedir=$(prefix)/include
   73.10  libdir=$(prefix)/lib
   73.11  
    74.1 --- a/tools/libxc/xc_dom_boot.c	Thu Aug 07 11:47:34 2008 +0900
    74.2 +++ b/tools/libxc/xc_dom_boot.c	Thu Aug 07 11:57:34 2008 +0900
    74.3 @@ -4,7 +4,7 @@
    74.4   * This is the code which actually boots a fresh
    74.5   * prepared domain image as xen guest domain.
    74.6   *
    74.7 - * ==>  this is the only domain bilder code piece
    74.8 + * ==>  this is the only domain builder code piece
    74.9   *          where xen hypercalls are allowed        <==
   74.10   *
   74.11   * This code is licenced under the GPL.
   74.12 @@ -153,7 +153,7 @@ void *xc_dom_boot_domU_map(struct xc_dom
   74.13      int page_shift = XC_DOM_PAGE_SHIFT(dom);
   74.14      privcmd_mmap_entry_t *entries;
   74.15      void *ptr;
   74.16 -    int i, rc;
   74.17 +    int i;
   74.18      int err;
   74.19  
   74.20      entries = xc_dom_malloc(dom, count * sizeof(privcmd_mmap_entry_t));
   74.21 @@ -165,9 +165,13 @@ void *xc_dom_boot_domU_map(struct xc_dom
   74.22          return NULL;
   74.23      }
   74.24  
   74.25 -    ptr = mmap(NULL, count << page_shift, PROT_READ | PROT_WRITE,
   74.26 -               MAP_SHARED, dom->guest_xc, 0);
   74.27 -    if ( ptr == MAP_FAILED )
   74.28 +    for ( i = 0; i < count; i++ )
   74.29 +        entries[i].mfn = xc_dom_p2m_host(dom, pfn + i);
   74.30 +
   74.31 +    ptr = xc_map_foreign_ranges(dom->guest_xc, dom->guest_domid,
   74.32 +                count << page_shift, PROT_READ | PROT_WRITE, 1 << page_shift,
   74.33 +                entries, count);
   74.34 +    if ( ptr == NULL )
   74.35      {
   74.36          err = errno;
   74.37          xc_dom_panic(XC_INTERNAL_ERROR,
   74.38 @@ -177,22 +181,6 @@ void *xc_dom_boot_domU_map(struct xc_dom
   74.39          return NULL;
   74.40      }
   74.41  
   74.42 -    for ( i = 0; i < count; i++ )
   74.43 -    {
   74.44 -        entries[i].va = (uintptr_t) ptr + (i << page_shift);
   74.45 -        entries[i].mfn = xc_dom_p2m_host(dom, pfn + i);
   74.46 -        entries[i].npages = 1;
   74.47 -    }
   74.48 -
   74.49 -    rc = xc_map_foreign_ranges(dom->guest_xc, dom->guest_domid,
   74.50 -                               entries, count);
   74.51 -    if ( rc < 0 )
   74.52 -    {
   74.53 -        xc_dom_panic(XC_INTERNAL_ERROR,
   74.54 -                     "%s: failed to mmap domU pages 0x%" PRIpfn "+0x%" PRIpfn
   74.55 -                     " [xenctl, rc=%d]\n", __FUNCTION__, pfn, count, rc);
   74.56 -        return NULL;
   74.57 -    }
   74.58      return ptr;
   74.59  }
   74.60  
    75.1 --- a/tools/libxc/xc_domain_save.c	Thu Aug 07 11:47:34 2008 +0900
    75.2 +++ b/tools/libxc/xc_domain_save.c	Thu Aug 07 11:57:34 2008 +0900
    75.3 @@ -568,16 +568,19 @@ static xen_pfn_t *xc_map_m2p(int xc_hand
    75.4      unsigned long m2p_chunks, m2p_size;
    75.5      xen_pfn_t *m2p;
    75.6      xen_pfn_t *extent_start;
    75.7 -    int i, rc;
    75.8 +    int i;
    75.9  
   75.10 +    m2p = NULL;
   75.11      m2p_size   = M2P_SIZE(max_mfn);
   75.12      m2p_chunks = M2P_CHUNKS(max_mfn);
   75.13  
   75.14      xmml.max_extents = m2p_chunks;
   75.15 -    if ( !(extent_start = malloc(m2p_chunks * sizeof(xen_pfn_t))) )
   75.16 +
   75.17 +    extent_start = calloc(m2p_chunks, sizeof(xen_pfn_t));
   75.18 +    if ( !extent_start )
   75.19      {
   75.20          ERROR("failed to allocate space for m2p mfns");
   75.21 -        return NULL;
   75.22 +        goto err0;
   75.23      }
   75.24      set_xen_guest_handle(xmml.extent_start, extent_start);
   75.25  
   75.26 @@ -585,41 +588,36 @@ static xen_pfn_t *xc_map_m2p(int xc_hand
   75.27           (xmml.nr_extents != m2p_chunks) )
   75.28      {
   75.29          ERROR("xc_get_m2p_mfns");
   75.30 -        return NULL;
   75.31 +        goto err1;
   75.32      }
   75.33  
   75.34 -    if ( (m2p = mmap(NULL, m2p_size, prot,
   75.35 -                     MAP_SHARED, xc_handle, 0)) == MAP_FAILED )
   75.36 -    {
   75.37 -        ERROR("failed to mmap m2p");
   75.38 -        return NULL;
   75.39 -    }
   75.40 -
   75.41 -    if ( !(entries = malloc(m2p_chunks * sizeof(privcmd_mmap_entry_t))) )
   75.42 +    entries = calloc(m2p_chunks, sizeof(privcmd_mmap_entry_t));
   75.43 +    if (entries == NULL)
   75.44      {
   75.45          ERROR("failed to allocate space for mmap entries");
   75.46 -        return NULL;
   75.47 +        goto err1;
   75.48      }
   75.49  
   75.50      for ( i = 0; i < m2p_chunks; i++ )
   75.51 -    {
   75.52 -        entries[i].va = (unsigned long)(((void *)m2p) + (i * M2P_CHUNK_SIZE));
   75.53          entries[i].mfn = extent_start[i];
   75.54 -        entries[i].npages = M2P_CHUNK_SIZE >> PAGE_SHIFT;
   75.55 -    }
   75.56  
   75.57 -    if ( (rc = xc_map_foreign_ranges(xc_handle, DOMID_XEN,
   75.58 -                                     entries, m2p_chunks)) < 0 )
   75.59 +    m2p = xc_map_foreign_ranges(xc_handle, DOMID_XEN,
   75.60 +			m2p_size, prot, M2P_CHUNK_SIZE,
   75.61 +			entries, m2p_chunks);
   75.62 +    if (m2p == NULL)
   75.63      {
   75.64 -        ERROR("xc_mmap_foreign_ranges failed (rc = %d)", rc);
   75.65 -        return NULL;
   75.66 +        ERROR("xc_mmap_foreign_ranges failed");
   75.67 +        goto err2;
   75.68      }
   75.69  
   75.70      m2p_mfn0 = entries[0].mfn;
   75.71  
   75.72 -    free(extent_start);
   75.73 +err2:
   75.74      free(entries);
   75.75 +err1:
   75.76 +    free(extent_start);
   75.77  
   75.78 +err0:
   75.79      return m2p;
   75.80  }
   75.81  
    76.1 --- a/tools/libxc/xc_hvm_build.c	Thu Aug 07 11:47:34 2008 +0900
    76.2 +++ b/tools/libxc/xc_hvm_build.c	Thu Aug 07 11:57:34 2008 +0900
    76.3 @@ -115,42 +115,32 @@ static int loadelfimage(
    76.4      struct elf_binary *elf, int xch, uint32_t dom, unsigned long *parray)
    76.5  {
    76.6      privcmd_mmap_entry_t *entries = NULL;
    76.7 -    int pages = (elf->pend - elf->pstart + PAGE_SIZE - 1) >> PAGE_SHIFT;
    76.8 +    size_t pages = (elf->pend - elf->pstart + PAGE_SIZE - 1) >> PAGE_SHIFT;
    76.9      int i, rc = -1;
   76.10  
   76.11      /* Map address space for initial elf image. */
   76.12 -    entries = malloc(pages * sizeof(privcmd_mmap_entry_t));
   76.13 +    entries = calloc(pages, sizeof(privcmd_mmap_entry_t));
   76.14      if ( entries == NULL )
   76.15          goto err;
   76.16 -    elf->dest = mmap(NULL, pages << PAGE_SHIFT, PROT_READ | PROT_WRITE,
   76.17 -                     MAP_SHARED, xch, 0);
   76.18 -    if ( elf->dest == MAP_FAILED )
   76.19 -        goto err;
   76.20  
   76.21      for ( i = 0; i < pages; i++ )
   76.22 -    {
   76.23 -        entries[i].va = (uintptr_t)elf->dest + (i << PAGE_SHIFT);
   76.24          entries[i].mfn = parray[(elf->pstart >> PAGE_SHIFT) + i];
   76.25 -        entries[i].npages = 1;
   76.26 -    }
   76.27  
   76.28 -    rc = xc_map_foreign_ranges(xch, dom, entries, pages);
   76.29 -    if ( rc < 0 )
   76.30 +    elf->dest = xc_map_foreign_ranges(
   76.31 +        xch, dom, pages << PAGE_SHIFT, PROT_READ | PROT_WRITE, 1 << PAGE_SHIFT,
   76.32 +        entries, pages);
   76.33 +    if ( elf->dest == NULL )
   76.34          goto err;
   76.35  
   76.36      /* Load the initial elf image. */
   76.37      elf_load_binary(elf);
   76.38      rc = 0;
   76.39  
   76.40 +    munmap(elf->dest, pages << PAGE_SHIFT);
   76.41 +    elf->dest = NULL;
   76.42 +
   76.43   err:
   76.44 -    if ( elf->dest )
   76.45 -    {
   76.46 -        munmap(elf->dest, pages << PAGE_SHIFT);
   76.47 -        elf->dest = NULL;
   76.48 -    }
   76.49 -
   76.50 -    if ( entries )
   76.51 -        free(entries);
   76.52 +    free(entries);
   76.53  
   76.54      return rc;
   76.55  }
   76.56 @@ -239,7 +229,7 @@ static int setup_guest(int xc_handle,
   76.57          if ( ((count | cur_pages) & (SUPERPAGE_NR_PFNS - 1)) == 0 )
   76.58          {
   76.59              long done;
   76.60 -            xen_pfn_t sp_extents[2048 >> SUPERPAGE_PFN_SHIFT];
   76.61 +            xen_pfn_t sp_extents[count >> SUPERPAGE_PFN_SHIFT];
   76.62              struct xen_memory_reservation sp_req = {
   76.63                  .nr_extents   = count >> SUPERPAGE_PFN_SHIFT,
   76.64                  .extent_order = SUPERPAGE_PFN_SHIFT,
    77.1 --- a/tools/libxc/xc_linux.c	Thu Aug 07 11:47:34 2008 +0900
    77.2 +++ b/tools/libxc/xc_linux.c	Thu Aug 07 11:57:34 2008 +0900
    77.3 @@ -118,16 +118,41 @@ void *xc_map_foreign_range(int xc_handle
    77.4      return addr;
    77.5  }
    77.6  
    77.7 -int xc_map_foreign_ranges(int xc_handle, uint32_t dom,
    77.8 -                          privcmd_mmap_entry_t *entries, int nr)
    77.9 +void *xc_map_foreign_ranges(int xc_handle, uint32_t dom,
   77.10 +                            size_t size, int prot, size_t chunksize,
   77.11 +                            privcmd_mmap_entry_t entries[], int nentries)
   77.12  {
   77.13      privcmd_mmap_t ioctlx;
   77.14 +    int i, rc;
   77.15 +    void *addr;
   77.16  
   77.17 -    ioctlx.num   = nr;
   77.18 +    addr = mmap(NULL, size, prot, MAP_SHARED, xc_handle, 0);
   77.19 +    if ( addr == MAP_FAILED )
   77.20 +        goto mmap_failed;
   77.21 +
   77.22 +    for ( i = 0; i < nentries; i++ )
   77.23 +    {
   77.24 +        entries[i].va = (unsigned long)addr + (i * chunksize);
   77.25 +        entries[i].npages = chunksize >> PAGE_SHIFT;
   77.26 +    }
   77.27 +
   77.28 +    ioctlx.num   = nentries;
   77.29      ioctlx.dom   = dom;
   77.30      ioctlx.entry = entries;
   77.31  
   77.32 -    return ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx);
   77.33 +    rc = ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx);
   77.34 +    if ( rc )
   77.35 +        goto ioctl_failed;
   77.36 +
   77.37 +    return addr;
   77.38 +
   77.39 +ioctl_failed:
   77.40 +    rc = munmap(addr, size);
   77.41 +    if ( rc == -1 )
   77.42 +        ERROR("%s: error in error path\n", __FUNCTION__);
   77.43 +
   77.44 +mmap_failed:
   77.45 +    return NULL;
   77.46  }
   77.47  
   77.48  static int do_privcmd(int xc_handle, unsigned int cmd, unsigned long data)
    78.1 --- a/tools/libxc/xc_minios.c	Thu Aug 07 11:47:34 2008 +0900
    78.2 +++ b/tools/libxc/xc_minios.c	Thu Aug 07 11:57:34 2008 +0900
    78.3 @@ -15,6 +15,7 @@
    78.4  #include <os.h>
    78.5  #include <mm.h>
    78.6  #include <lib.h>
    78.7 +#include <gntmap.h>
    78.8  #include <events.h>
    78.9  #include <wait.h>
   78.10  #include <sys/mman.h>
   78.11 @@ -76,17 +77,31 @@ void *xc_map_foreign_range(int xc_handle
   78.12      return map_frames_ex(&mfn, size / getpagesize(), 0, 1, 1, dom, 0, pt_prot);
   78.13  }
   78.14  
   78.15 -int xc_map_foreign_ranges(int xc_handle, uint32_t dom,
   78.16 -                          privcmd_mmap_entry_t *entries, int nr)
   78.17 +void *xc_map_foreign_ranges(int xc_handle, uint32_t dom,
   78.18 +                            size_t size, int prot, size_t chunksize,
   78.19 +                            privcmd_mmap_entry_t entries[], int nentries)
   78.20  {
   78.21 -    int i;
   78.22 -    for (i = 0; i < nr; i++) {
   78.23 -	unsigned long mfn = entries[i].mfn;
   78.24 -        do_map_frames(entries[i].va, &mfn, entries[i].npages, 0, 1, dom, 0, L1_PROT);
   78.25 -    }
   78.26 -    return 0;
   78.27 +    unsigned long mfns[size / PAGE_SIZE];
   78.28 +    int i, j, n;
   78.29 +    unsigned long pt_prot = 0;
   78.30 +#ifdef __ia64__
   78.31 +    /* TODO */
   78.32 +#else
   78.33 +    if (prot & PROT_READ)
   78.34 +	pt_prot = L1_PROT_RO;
   78.35 +    if (prot & PROT_WRITE)
   78.36 +	pt_prot = L1_PROT;
   78.37 +#endif
   78.38 +
   78.39 +    n = 0;
   78.40 +    for (i = 0; i < nentries; i++)
   78.41 +        for (j = 0; j < chunksize / PAGE_SIZE; j++)
   78.42 +            mfns[n++] = entries[i].mfn + j;
   78.43 +
   78.44 +    return map_frames_ex(mfns, n, 1, 0, 1, dom, 0, pt_prot);
   78.45  }
   78.46  
   78.47 +
   78.48  int do_xen_hypercall(int xc_handle, privcmd_hypercall_t *hypercall)
   78.49  {
   78.50      multicall_entry_t call;
   78.51 @@ -102,8 +117,8 @@ int do_xen_hypercall(int xc_handle, priv
   78.52  	errno = -ret;
   78.53  	return -1;
   78.54      }
   78.55 -    if (call.result < 0) {
   78.56 -        errno = -call.result;
   78.57 +    if ((long) call.result < 0) {
   78.58 +        errno = - (long) call.result;
   78.59          return -1;
   78.60      }
   78.61      return call.result;
   78.62 @@ -244,8 +259,11 @@ int xc_evtchn_unbind(int xce_handle, evt
   78.63  	    files[xce_handle].evtchn.ports[i].port = -1;
   78.64  	    break;
   78.65  	}
   78.66 -    if (i == MAX_EVTCHN_PORTS)
   78.67 +    if (i == MAX_EVTCHN_PORTS) {
   78.68  	printf("Warning: couldn't find port %"PRId32" for xc handle %x\n", port, xce_handle);
   78.69 +	errno = -EINVAL;
   78.70 +	return -1;
   78.71 +    }
   78.72      files[xce_handle].evtchn.ports[i].bound = 0;
   78.73      unbind_evtchn(port);
   78.74      return 0;
   78.75 @@ -278,18 +296,24 @@ evtchn_port_or_error_t xc_evtchn_pending
   78.76  {
   78.77      int i;
   78.78      unsigned long flags;
   78.79 +    evtchn_port_t ret = -1;
   78.80 +
   78.81      local_irq_save(flags);
   78.82 +    files[xce_handle].read = 0;
   78.83      for (i = 0; i < MAX_EVTCHN_PORTS; i++) {
   78.84 -	evtchn_port_t port = files[xce_handle].evtchn.ports[i].port;
   78.85 -	if (port != -1 && files[xce_handle].evtchn.ports[i].pending) {
   78.86 -	    files[xce_handle].evtchn.ports[i].pending = 0;
   78.87 -	    local_irq_restore(flags);
   78.88 -	    return port;
   78.89 -	}
   78.90 +        evtchn_port_t port = files[xce_handle].evtchn.ports[i].port;
   78.91 +        if (port != -1 && files[xce_handle].evtchn.ports[i].pending) {
   78.92 +            if (ret == -1) {
   78.93 +                ret = port;
   78.94 +                files[xce_handle].evtchn.ports[i].pending = 0;
   78.95 +            } else {
   78.96 +                files[xce_handle].read = 1;
   78.97 +                break;
   78.98 +            }
   78.99 +        }
  78.100      }
  78.101 -    files[xce_handle].read = 0;
  78.102      local_irq_restore(flags);
  78.103 -    return -1;
  78.104 +    return ret;
  78.105  }
  78.106  
  78.107  int xc_evtchn_unmask(int xce_handle, evtchn_port_t port)
  78.108 @@ -304,6 +328,88 @@ void discard_file_cache(int fd, int flus
  78.109      if (flush)
  78.110          fsync(fd);
  78.111  }
  78.112 +
  78.113 +int xc_gnttab_open(void)
  78.114 +{
  78.115 +    int xcg_handle;
  78.116 +    xcg_handle = alloc_fd(FTYPE_GNTMAP);
  78.117 +    gntmap_init(&files[xcg_handle].gntmap);
  78.118 +    return xcg_handle;
  78.119 +}
  78.120 +
  78.121 +int xc_gnttab_close(int xcg_handle)
  78.122 +{
  78.123 +    gntmap_fini(&files[xcg_handle].gntmap);
  78.124 +    files[xcg_handle].type = FTYPE_NONE;
  78.125 +    return 0;
  78.126 +}
  78.127 +
  78.128 +void *xc_gnttab_map_grant_ref(int xcg_handle,
  78.129 +                              uint32_t domid,
  78.130 +                              uint32_t ref,
  78.131 +                              int prot)
  78.132 +{
  78.133 +    return gntmap_map_grant_refs(&files[xcg_handle].gntmap,
  78.134 +                                 1,
  78.135 +                                 &domid, 0,
  78.136 +                                 &ref,
  78.137 +                                 prot & PROT_WRITE);
  78.138 +}
  78.139 +
  78.140 +void *xc_gnttab_map_grant_refs(int xcg_handle,
  78.141 +                               uint32_t count,
  78.142 +                               uint32_t *domids,
  78.143 +                               uint32_t *refs,
  78.144 +                               int prot)
  78.145 +{
  78.146 +    return gntmap_map_grant_refs(&files[xcg_handle].gntmap,
  78.147 +                                 count,
  78.148 +                                 domids, 1,
  78.149 +                                 refs,
  78.150 +                                 prot & PROT_WRITE);
  78.151 +}
  78.152 +
  78.153 +void *xc_gnttab_map_domain_grant_refs(int xcg_handle,
  78.154 +                                      uint32_t count,
  78.155 +                                      uint32_t domid,
  78.156 +                                      uint32_t *refs,
  78.157 +                                      int prot)
  78.158 +{
  78.159 +    return gntmap_map_grant_refs(&files[xcg_handle].gntmap,
  78.160 +                                 count,
  78.161 +                                 &domid, 0,
  78.162 +                                 refs,
  78.163 +                                 prot & PROT_WRITE);
  78.164 +}
  78.165 +
  78.166 +int xc_gnttab_munmap(int xcg_handle,
  78.167 +                     void *start_address,
  78.168 +                     uint32_t count)
  78.169 +{
  78.170 +    int ret;
  78.171 +    ret = gntmap_munmap(&files[xcg_handle].gntmap,
  78.172 +                        (unsigned long) start_address,
  78.173 +                        count);
  78.174 +    if (ret < 0) {
  78.175 +        errno = -ret;
  78.176 +        return -1;
  78.177 +    }
  78.178 +    return ret;
  78.179 +}
  78.180 +
  78.181 +int xc_gnttab_set_max_grants(int xcg_handle,
  78.182 +                             uint32_t count)
  78.183 +{
  78.184 +    int ret;
  78.185 +    ret = gntmap_set_max_grants(&files[xcg_handle].gntmap,
  78.186 +                                count);
  78.187 +    if (ret < 0) {
  78.188 +        errno = -ret;
  78.189 +        return -1;
  78.190 +    }
  78.191 +    return ret;
  78.192 +}
  78.193 +
  78.194  /*
  78.195   * Local variables:
  78.196   * mode: C
    79.1 --- a/tools/libxc/xc_netbsd.c	Thu Aug 07 11:47:34 2008 +0900
    79.2 +++ b/tools/libxc/xc_netbsd.c	Thu Aug 07 11:57:34 2008 +0900
    79.3 @@ -11,7 +11,6 @@
    79.4  
    79.5  #include "xc_private.h"
    79.6  
    79.7 -#include <xen/memory.h>
    79.8  #include <xen/sys/evtchn.h>
    79.9  #include <unistd.h>
   79.10  #include <fcntl.h>
   79.11 @@ -114,23 +113,43 @@ void *xc_map_foreign_range(int xc_handle
   79.12      return addr;
   79.13  }
   79.14  
   79.15 -int xc_map_foreign_ranges(int xc_handle, uint32_t dom,
   79.16 -                          privcmd_mmap_entry_t *entries, int nr)
   79.17 +void *xc_map_foreign_ranges(int xc_handle, uint32_t dom,
   79.18 +                            size_t size, int prot, size_t chunksize,
   79.19 +                            privcmd_mmap_entry_t entries[], int nentries)
   79.20  {
   79.21 -    privcmd_mmap_t ioctlx;
   79.22 -    int err;
   79.23 +	privcmd_mmap_t ioctlx;
   79.24 +	int i, rc;
   79.25 +	void *addr;
   79.26 +
   79.27 +	addr = mmap(NULL, size, prot, MAP_ANON | MAP_SHARED, -1, 0);
   79.28 +	if (addr == MAP_FAILED)
   79.29 +		goto mmap_failed;
   79.30 +
   79.31 +	for (i = 0; i < nentries; i++) {
   79.32 +		entries[i].va = (uintptr_t)addr + (i * chunksize);
   79.33 +		entries[i].npages = chunksize >> PAGE_SHIFT;
   79.34 +	}
   79.35  
   79.36 -    ioctlx.num   = nr;
   79.37 -    ioctlx.dom   = dom;
   79.38 -    ioctlx.entry = entries;
   79.39 +	ioctlx.num   = nentries;
   79.40 +	ioctlx.dom   = dom;
   79.41 +	ioctlx.entry = entries;
   79.42 +
   79.43 +	rc = ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx);
   79.44 +	if (rc)
   79.45 +		goto ioctl_failed;
   79.46 +
   79.47 +	return addr;
   79.48  
   79.49 -    err = ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx);
   79.50 -    if (err == 0)
   79.51 -	return 0;
   79.52 -    else
   79.53 -	return -errno;
   79.54 +ioctl_failed:
   79.55 +	rc = munmap(addr, size);
   79.56 +	if (rc == -1)
   79.57 +		ERROR("%s: error in error path\n", __FUNCTION__);
   79.58 +
   79.59 +mmap_failed:
   79.60 +	return NULL;
   79.61  }
   79.62  
   79.63 +
   79.64  static int do_privcmd(int xc_handle, unsigned int cmd, unsigned long data)
   79.65  {
   79.66      int err = ioctl(xc_handle, cmd, data);
    80.1 --- a/tools/libxc/xc_physdev.c	Thu Aug 07 11:47:34 2008 +0900
    80.2 +++ b/tools/libxc/xc_physdev.c	Thu Aug 07 11:57:34 2008 +0900
    80.3 @@ -22,7 +22,6 @@ int xc_physdev_pci_access_modify(int xc_
    80.4  
    80.5  int xc_physdev_map_pirq(int xc_handle,
    80.6                          int domid,
    80.7 -                        int type,
    80.8                          int index,
    80.9                          int *pirq)
   80.10  {
   80.11 @@ -33,7 +32,7 @@ int xc_physdev_map_pirq(int xc_handle,
   80.12          return -EINVAL;
   80.13  
   80.14      map.domid = domid;
   80.15 -    map.type = type;
   80.16 +    map.type = MAP_PIRQ_TYPE_GSI;
   80.17      map.index = index;
   80.18      map.pirq = *pirq;
   80.19  
   80.20 @@ -47,7 +46,6 @@ int xc_physdev_map_pirq(int xc_handle,
   80.21  
   80.22  int xc_physdev_map_pirq_msi(int xc_handle,
   80.23                              int domid,
   80.24 -                            int type,
   80.25                              int index,
   80.26                              int *pirq,
   80.27                              int devfn,
   80.28 @@ -62,7 +60,7 @@ int xc_physdev_map_pirq_msi(int xc_handl
   80.29          return -EINVAL;
   80.30  
   80.31      map.domid = domid;
   80.32 -    map.type = type;
   80.33 +    map.type = MAP_PIRQ_TYPE_MSI;
   80.34      map.index = index;
   80.35      map.pirq = *pirq;
   80.36      map.msi_info.devfn = devfn;
    81.1 --- a/tools/libxc/xc_private.h	Thu Aug 07 11:47:34 2008 +0900
    81.2 +++ b/tools/libxc/xc_private.h	Thu Aug 07 11:57:34 2008 +0900
    81.3 @@ -184,8 +184,9 @@ static inline int do_sysctl(int xc_handl
    81.4      return ret;
    81.5  }
    81.6  
    81.7 -int xc_map_foreign_ranges(int xc_handle, uint32_t dom,
    81.8 -                          privcmd_mmap_entry_t *entries, int nr);
    81.9 +void *xc_map_foreign_ranges(int xc_handle, uint32_t dom,
   81.10 +                            size_t size, int prot, size_t chunksize,
   81.11 +                            privcmd_mmap_entry_t entries[], int nentries);
   81.12  
   81.13  void *map_domain_va_core(unsigned long domfd, int cpu, void *guest_va,
   81.14                           vcpu_guest_context_any_t *ctxt);
    82.1 --- a/tools/libxc/xc_solaris.c	Thu Aug 07 11:47:34 2008 +0900
    82.2 +++ b/tools/libxc/xc_solaris.c	Thu Aug 07 11:57:34 2008 +0900
    82.3 @@ -109,18 +109,41 @@ void *xc_map_foreign_range(int xc_handle
    82.4      return addr;
    82.5  }
    82.6  
    82.7 -int xc_map_foreign_ranges(int xc_handle, uint32_t dom,
    82.8 -                          privcmd_mmap_entry_t *entries, int nr)
    82.9 +void *xc_map_foreign_ranges(int xc_handle, uint32_t dom,
   82.10 +                            size_t size, int prot, size_t chunksize,
   82.11 +                            privcmd_mmap_entry_t entries[], int nentries)
   82.12  {
   82.13      privcmd_mmap_t ioctlx;
   82.14 +    int i, rc;
   82.15 +    void *addr;
   82.16  
   82.17 -    ioctlx.num   = nr;
   82.18 +    addr = mmap(NULL, size, prot, MAP_SHARED, xc_handle, 0);
   82.19 +    if (addr == MAP_FAILED)
   82.20 +        goto mmap_failed;
   82.21 +
   82.22 +    for (i = 0; i < nentries; i++) {
   82.23 +        entries[i].va = (uintptr_t)addr + (i * chunksize);
   82.24 +        entries[i].npages = chunksize >> PAGE_SHIFT;
   82.25 +    }
   82.26 +
   82.27 +    ioctlx.num   = nentries;
   82.28      ioctlx.dom   = dom;
   82.29      ioctlx.entry = entries;
   82.30  
   82.31 -    return ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx);
   82.32 +    rc = ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx);
   82.33 +    if (rc)
   82.34 +        goto ioctl_failed;
   82.35 +
   82.36 +ioctl_failed:
   82.37 +    rc = munmap(addr, size);
   82.38 +    if (rc == -1)
   82.39 +        ERROR("%s: error in error path\n", __FUNCTION__);
   82.40 +
   82.41 +mmap_failed:
   82.42 +    return NULL;
   82.43  }
   82.44  
   82.45 +
   82.46  static int do_privcmd(int xc_handle, unsigned int cmd, unsigned long data)
   82.47  {
   82.48      return ioctl(xc_handle, cmd, data);
    83.1 --- a/tools/libxc/xenctrl.h	Thu Aug 07 11:47:34 2008 +0900
    83.2 +++ b/tools/libxc/xenctrl.h	Thu Aug 07 11:57:34 2008 +0900
    83.3 @@ -907,13 +907,11 @@ int xc_gnttab_set_max_grants(int xcg_han
    83.4  
    83.5  int xc_physdev_map_pirq(int xc_handle,
    83.6                          int domid,
    83.7 -                        int type,
    83.8                          int index,
    83.9                          int *pirq);
   83.10  
   83.11  int xc_physdev_map_pirq_msi(int xc_handle,
   83.12                              int domid,
   83.13 -                            int type,
   83.14                              int index,
   83.15                              int *pirq,
   83.16                              int devfn,
    84.1 --- a/tools/pygrub/src/pygrub	Thu Aug 07 11:47:34 2008 +0900
    84.2 +++ b/tools/pygrub/src/pygrub	Thu Aug 07 11:57:34 2008 +0900
    84.3 @@ -21,7 +21,7 @@ import platform
    84.4  import curses, _curses, curses.wrapper, curses.textpad, curses.ascii
    84.5  import getopt
    84.6  
    84.7 -sys.path = [ '/usr/lib/python' ] + sys.path
    84.8 +sys.path = [ '/usr/lib/python', '/usr/lib64/python' ] + sys.path
    84.9  
   84.10  import fsimage
   84.11  import grub.GrubConf
    85.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Thu Aug 07 11:47:34 2008 +0900
    85.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Thu Aug 07 11:57:34 2008 +0900
    85.3 @@ -958,8 +958,7 @@ static PyObject *pyxc_physdev_map_pirq(P
    85.4      if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iii", kwd_list,
    85.5                                        &dom, &index, &pirq) )
    85.6          return NULL;
    85.7 -    ret = xc_physdev_map_pirq(xc->xc_handle, dom, MAP_PIRQ_TYPE_GSI,
    85.8 -                             index, &pirq);
    85.9 +    ret = xc_physdev_map_pirq(xc->xc_handle, dom, index, &pirq);
   85.10      if ( ret != 0 )
   85.11            return pyxc_error_to_exception();
   85.12      return PyLong_FromUnsignedLong(pirq);
    86.1 --- a/tools/python/xen/util/pci.py	Thu Aug 07 11:47:34 2008 +0900
    86.2 +++ b/tools/python/xen/util/pci.py	Thu Aug 07 11:57:34 2008 +0900
    86.3 @@ -44,6 +44,12 @@ PCI_STATUS = 0x6
    86.4  PCI_CLASS_DEVICE = 0x0a
    86.5  PCI_CLASS_BRIDGE_PCI = 0x0604
    86.6  
    86.7 +PCI_HEADER_TYPE = 0x0e
    86.8 +PCI_HEADER_TYPE_MASK = 0x7f
    86.9 +PCI_HEADER_TYPE_NORMAL  = 0
   86.10 +PCI_HEADER_TYPE_BRIDGE  = 1
   86.11 +PCI_HEADER_TYPE_CARDBUS = 2
   86.12 +
   86.13  PCI_CAPABILITY_LIST = 0x34
   86.14  PCI_CB_BRIDGE_CONTROL = 0x3e
   86.15  PCI_BRIDGE_CTL_BUS_RESET= 0x40
   86.16 @@ -57,6 +63,12 @@ PCI_EXP_DEVCAP_FLR = (0x1 << 28)
   86.17  PCI_EXP_DEVCTL = 0x8
   86.18  PCI_EXP_DEVCTL_FLR = (0x1 << 15)
   86.19  
   86.20 +PCI_CAP_ID_PM = 0x01
   86.21 +PCI_PM_CTRL = 4
   86.22 +PCI_PM_CTRL_NO_SOFT_RESET = 0x0004
   86.23 +PCI_PM_CTRL_STATE_MASK = 0x0003
   86.24 +PCI_D3hot = 3
   86.25 +
   86.26  PCI_CAP_ID_AF = 0x13
   86.27  PCI_AF_CAPs   = 0x3
   86.28  PCI_AF_CAPs_TP_FLR = 0x3
   86.29 @@ -105,15 +117,22 @@ def parse_hex(val):
   86.30          return None
   86.31  
   86.32  def parse_pci_name(pci_name_string):
   86.33 -    # Format: xxxx:xx:xx:x
   86.34 -    s = pci_name_string
   86.35 -    s = s.split(':')
   86.36 -    dom = parse_hex(s[0])
   86.37 -    bus = parse_hex(s[1])
   86.38 -    s = s[2].split('.')
   86.39 -    dev = parse_hex(s[0])
   86.40 -    func =  parse_hex(s[1])
   86.41 -    return (dom, bus, dev, func)
   86.42 +    pci_match = re.match(r"((?P<domain>[0-9a-fA-F]{1,4})[:,])?" + \
   86.43 +            r"(?P<bus>[0-9a-fA-F]{1,2})[:,]" + \
   86.44 +            r"(?P<slot>[0-9a-fA-F]{1,2})[.,]" + \
   86.45 +            r"(?P<func>[0-7])$", pci_name_string)
   86.46 +    if pci_match is None:
   86.47 +        raise PciDeviceParseError(('Failed to parse pci device name: %s' %
   86.48 +            pci_name_string))
   86.49 +    pci_dev_info = pci_match.groupdict('0')
   86.50 +
   86.51 +    domain = parse_hex(pci_dev_info['domain'])
   86.52 +    bus = parse_hex(pci_dev_info['bus'])
   86.53 +    slot = parse_hex(pci_dev_info['slot'])
   86.54 +    func = parse_hex(pci_dev_info['func'])
   86.55 +
   86.56 +    return (domain, bus, slot, func)
   86.57 + 
   86.58  
   86.59  def find_sysfs_mnt():
   86.60      global sysfs_mnt_point
   86.61 @@ -169,14 +188,14 @@ def create_lspci_info():
   86.62  
   86.63      # Execute 'lspci' command and parse the result.
   86.64      # If the command does not exist, lspci_info will be kept blank ({}).
   86.65 -    for paragraph in os.popen(LSPCI_CMD + ' -vmmD').read().split('\n\n'):
   86.66 +    for paragraph in os.popen(LSPCI_CMD + ' -vmm').read().split('\n\n'):
   86.67          device_name = None
   86.68          device_info = {}
   86.69          for line in paragraph.split('\n'):
   86.70              try:
   86.71                  (opt, value) = line.split(':\t')
   86.72                  if opt == 'Slot':
   86.73 -                    device_name = value
   86.74 +                    device_name = PCI_DEV_FORMAT_STR % parse_pci_name(value)
   86.75                  else:
   86.76                      device_info[opt] = value
   86.77              except:
   86.78 @@ -246,18 +265,8 @@ def transform_list(target, src):
   86.79      return  result
   86.80  
   86.81  def check_FLR_capability(dev_list):
   86.82 -    i = len(dev_list)
   86.83 -    if i == 0:
   86.84 +    if len(dev_list) == 0:
   86.85          return []
   86.86 -    i = i - 1;
   86.87 -    while i >= 0:
   86.88 -        dev = dev_list[i]
   86.89 -        if dev.bus == 0:
   86.90 -            if dev.dev_type == DEV_TYPE_PCIe_ENDPOINT and not dev.pcie_flr:
   86.91 -                del dev_list[i]
   86.92 -            elif dev.dev_type == DEV_TYPE_PCI and not dev.pci_af_flr:
   86.93 -                del dev_list[i]
   86.94 -        i = i - 1
   86.95  
   86.96      pci_list = []
   86.97      pci_dev_dict = {}
   86.98 @@ -270,6 +279,8 @@ def check_FLR_capability(dev_list):
   86.99          for pci in pci_list:
  86.100              if isinstance(pci, types.StringTypes):
  86.101                  dev = pci_dev_dict[pci]
  86.102 +                if dev.bus == 0:
  86.103 +                    continue
  86.104                  if dev.dev_type == DEV_TYPE_PCIe_ENDPOINT and not dev.pcie_flr:
  86.105                      coassigned_pci_list = dev.find_all_the_multi_functions()
  86.106                      need_transform = True
  86.107 @@ -338,13 +349,6 @@ class PciDeviceAssignmentError(Exception
  86.108          return 'pci: impproper device assignment spcified: ' + \
  86.109              self.message
  86.110  
  86.111 -class PciDeviceFlrError(PciDeviceAssignmentError):
  86.112 -    def __init__(self,msg):
  86.113 -        self.message = msg
  86.114 -    def __str__(self):
  86.115 -        return 'Can not find a suitable FLR method for the device(s): ' + \
  86.116 -            self.message
  86.117 -
  86.118  class PciDevice:
  86.119      def __init__(self, domain, bus, slot, func):
  86.120          self.domain = domain
  86.121 @@ -480,6 +484,27 @@ class PciDevice:
  86.122          # Restore the config spaces
  86.123          restore_pci_conf_space((pci_list, cfg_list))
  86.124          
  86.125 +    def do_Dstate_transition(self):
  86.126 +        pos = self.find_cap_offset(PCI_CAP_ID_PM)
  86.127 +        if pos == 0:
  86.128 +            return 
  86.129 +        
  86.130 +        (pci_list, cfg_list) = save_pci_conf_space([self.name])
  86.131 +        
  86.132 +        # Enter D3hot without soft reset
  86.133 +        pm_ctl = self.pci_conf_read32(pos + PCI_PM_CTRL)
  86.134 +        pm_ctl |= PCI_PM_CTRL_NO_SOFT_RESET
  86.135 +        pm_ctl &= ~PCI_PM_CTRL_STATE_MASK
  86.136 +        pm_ctl |= PCI_D3hot
  86.137 +        self.pci_conf_write32(pos + PCI_PM_CTRL, pm_ctl)
  86.138 +        time.sleep(0.010)
  86.139 +
  86.140 +        # From D3hot to D0
  86.141 +        self.pci_conf_write32(pos + PCI_PM_CTRL, 0)
  86.142 +        time.sleep(0.010)
  86.143 +
  86.144 +        restore_pci_conf_space((pci_list, cfg_list))
  86.145 +
  86.146      def find_all_the_multi_functions(self):
  86.147          sysfs_mnt = find_sysfs_mnt()
  86.148          pci_names = os.popen('ls ' + sysfs_mnt + SYSFS_PCI_DEVS_PATH).read()
  86.149 @@ -650,13 +675,16 @@ class PciDevice:
  86.150                  time.sleep(0.200)
  86.151                  restore_pci_conf_space((pci_list, cfg_list))
  86.152              else:
  86.153 -                funcs = self.find_all_the_multi_functions()
  86.154 -                self.devs_check_driver(funcs)
  86.155 +                if self.bus == 0:
  86.156 +                    self.do_Dstate_transition()
  86.157 +                else:
  86.158 +                    funcs = self.find_all_the_multi_functions()
  86.159 +                    self.devs_check_driver(funcs)
  86.160  
  86.161 -                parent = '%04x:%02x:%02x.%01x' % self.find_parent()
  86.162 +                    parent = '%04x:%02x:%02x.%01x' % self.find_parent()
  86.163  
  86.164 -                # Do Secondary Bus Reset.
  86.165 -                self.do_secondary_bus_reset(parent, funcs)
  86.166 +                    # Do Secondary Bus Reset.
  86.167 +                    self.do_secondary_bus_reset(parent, funcs)
  86.168          # PCI devices
  86.169          else:
  86.170              # For PCI device on host bus, we test "PCI Advanced Capabilities".
  86.171 @@ -669,9 +697,7 @@ class PciDevice:
  86.172                  restore_pci_conf_space((pci_list, cfg_list))
  86.173              else:
  86.174                  if self.bus == 0:
  86.175 -                    err_msg = 'pci: %s is not assignable: it is on bus 0, '+ \
  86.176 -                        'but it has no PCI Advanced Capabilities.'
  86.177 -                    raise PciDeviceFlrError(err_msg % self.name)
  86.178 +                    self.do_Dstate_transition()
  86.179                  else:
  86.180                      devs = self.find_coassigned_devices(False)
  86.181                      # Remove the element 0 which is a bridge
  86.182 @@ -690,12 +716,24 @@ class PciDevice:
  86.183                 self.name+SYSFS_PCI_DEV_CONFIG_PATH
  86.184          try:
  86.185              conf_file = open(path, 'rb')
  86.186 +            conf_file.seek(PCI_HEADER_TYPE)
  86.187 +            header_type = ord(conf_file.read(1)) & PCI_HEADER_TYPE_MASK
  86.188 +            if header_type == PCI_HEADER_TYPE_CARDBUS:
  86.189 +                return
  86.190              conf_file.seek(PCI_STATUS_OFFSET)
  86.191              status = ord(conf_file.read(1))
  86.192              if status&PCI_STATUS_CAP_MASK:
  86.193                  conf_file.seek(PCI_CAP_OFFSET)
  86.194                  capa_pointer = ord(conf_file.read(1))
  86.195 +                capa_count = 0
  86.196                  while capa_pointer:
  86.197 +                    if capa_pointer < 0x40:
  86.198 +                        raise PciDeviceParseError(
  86.199 +                            ('Broken capability chain: %s' % self.name))
  86.200 +                    capa_count += 1
  86.201 +                    if capa_count > 96:
  86.202 +                        raise PciDeviceParseError(
  86.203 +                            ('Looped capability chain: %s' % self.name))
  86.204                      conf_file.seek(capa_pointer)
  86.205                      capa_id = ord(conf_file.read(1))
  86.206                      capa_pointer = ord(conf_file.read(1))
    87.1 --- a/tools/python/xen/util/utils.py	Thu Aug 07 11:47:34 2008 +0900
    87.2 +++ b/tools/python/xen/util/utils.py	Thu Aug 07 11:57:34 2008 +0900
    87.3 @@ -1,6 +1,50 @@
    87.4  import traceback
    87.5  import sys
    87.6 +import os
    87.7  
    87.8  def exception_string(e):
    87.9          (ty,v,tb) = sys.exc_info()
   87.10          return traceback.format_exception_only(ty,v)
   87.11 +
   87.12 +def daemonize(prog, args, stdin_tmpfile=None):
   87.13 +    """Runs a program as a daemon with the list of arguments.  Returns the PID
   87.14 +    of the daemonized program, or returns 0 on error.
   87.15 +    """
   87.16 +    r, w = os.pipe()
   87.17 +    pid = os.fork()
   87.18 +
   87.19 +    if pid == 0:
   87.20 +        os.close(r)
   87.21 +        w = os.fdopen(w, 'w')
   87.22 +        os.setsid()
   87.23 +        try:
   87.24 +            pid2 = os.fork()
   87.25 +        except:
   87.26 +            pid2 = None
   87.27 +        if pid2 == 0:
   87.28 +            os.chdir("/")
   87.29 +            null_fd = os.open("/dev/null", os.O_RDWR)
   87.30 +            if stdin_tmpfile is not None:
   87.31 +                os.dup2(stdin_tmpfile.fileno(), 0)
   87.32 +            else:
   87.33 +                os.dup2(null_fd, 0)
   87.34 +            os.dup2(null_fd, 1)
   87.35 +            os.dup2(null_fd, 2)
   87.36 +            for fd in range(3, 256):
   87.37 +                try:
   87.38 +                    os.close(fd)
   87.39 +                except:
   87.40 +                    pass
   87.41 +            os.execvp(prog, args)
   87.42 +            os._exit(1)
   87.43 +        else:
   87.44 +            w.write(str(pid2 or 0))
   87.45 +            w.close()
   87.46 +            os._exit(0)
   87.47 +    os.close(w)
   87.48 +    r = os.fdopen(r)
   87.49 +    daemon_pid = int(r.read())
   87.50 +    r.close()
   87.51 +    os.waitpid(pid, 0)
   87.52 +    return daemon_pid
   87.53 +
    88.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Thu Aug 07 11:47:34 2008 +0900
    88.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Thu Aug 07 11:57:34 2008 +0900
    88.3 @@ -599,14 +599,17 @@ class XendDomainInfo:
    88.4                  new_dev['func'])
    88.5          bdf = xc.test_assign_device(self.domid, pci_str)
    88.6          if bdf != 0:
    88.7 +            if bdf == -1:
    88.8 +                raise VmError("failed to assign device: maybe the platform"
    88.9 +                              " doesn't support VT-d, or VT-d isn't enabled"
   88.10 +                              " properly?")
   88.11              bus = (bdf >> 16) & 0xff
   88.12              devfn = (bdf >> 8) & 0xff
   88.13              dev = (devfn >> 3) & 0x1f
   88.14              func = devfn & 0x7
   88.15 -            raise VmError("Fail to hot insert device(%x:%x.%x): maybe VT-d is "
   88.16 -                          "not enabled, or the device is not exist, or it "
   88.17 -                          "has already been assigned to other domain"
   88.18 -                          % (bus, dev, func))
   88.19 +            raise VmError("fail to assign device(%x:%x.%x): maybe it has"
   88.20 +                          " already been assigned to other domain, or maybe"
   88.21 +                          " it doesn't exist." % (bus, dev, func))
   88.22  
   88.23          bdf_str = "%s:%s:%s.%s@%s" % (new_dev['domain'],
   88.24                  new_dev['bus'],
   88.25 @@ -635,7 +638,10 @@ class XendDomainInfo:
   88.26                  self._waitForDevice(dev_type, devid)
   88.27              except VmError, ex:
   88.28                  del self.info['devices'][dev_uuid]
   88.29 -                if dev_type == 'tap':
   88.30 +                if dev_type == 'pci':
   88.31 +                    for dev in dev_config_dict['devs']:
   88.32 +                        XendAPIStore.deregister(dev['uuid'], 'DPCI')
   88.33 +                elif dev_type == 'tap':
   88.34                      self.info['vbd_refs'].remove(dev_uuid)
   88.35                  else:
   88.36                      self.info['%s_refs' % dev_type].remove(dev_uuid)
   88.37 @@ -2086,14 +2092,17 @@ class XendDomainInfo:
   88.38          if hvm and pci_str:
   88.39              bdf = xc.test_assign_device(self.domid, pci_str)
   88.40              if bdf != 0:
   88.41 +                if bdf == -1:
   88.42 +                    raise VmError("failed to assign device: maybe the platform"
   88.43 +                                  " doesn't support VT-d, or VT-d isn't enabled"
   88.44 +                                  " properly?")
   88.45                  bus = (bdf >> 16) & 0xff
   88.46                  devfn = (bdf >> 8) & 0xff
   88.47                  dev = (devfn >> 3) & 0x1f
   88.48                  func = devfn & 0x7
   88.49 -                raise VmError("Fail to assign device(%x:%x.%x): maybe VT-d is "
   88.50 -                              "not enabled, or the device is not exist, or it "
   88.51 -                              "has already been assigned to other domain"
   88.52 -                              % (bus, dev, func))
   88.53 +                raise VmError("fail to assign device(%x:%x.%x): maybe it has"
   88.54 +                              " already been assigned to other domain, or maybe"
   88.55 +                              " it doesn't exist." % (bus, dev, func))
   88.56  
   88.57          # register the domain in the list 
   88.58          from xen.xend import XendDomain
   88.59 @@ -2374,6 +2383,9 @@ class XendDomainInfo:
   88.60      def destroy(self):
   88.61          """Cleanup VM and destroy domain.  Nothrow guarantee."""
   88.62  
   88.63 +        if self.domid is None:
   88.64 +            return
   88.65 +
   88.66          log.debug("XendDomainInfo.destroy: domid=%s", str(self.domid))
   88.67  
   88.68          paths = self._prepare_phantom_paths()
    89.1 --- a/tools/python/xen/xend/image.py	Thu Aug 07 11:47:34 2008 +0900
    89.2 +++ b/tools/python/xen/xend/image.py	Thu Aug 07 11:57:34 2008 +0900
    89.3 @@ -114,7 +114,7 @@ class ImageHandler:
    89.4  
    89.5          self.display = vmConfig['platform'].get('display')
    89.6          self.xauthority = vmConfig['platform'].get('xauthority')
    89.7 -        self.vncconsole = vmConfig['platform'].get('vncconsole')
    89.8 +        self.vncconsole = int(vmConfig['platform'].get('vncconsole', 0))
    89.9          self.dmargs = self.parseDeviceModelArgs(vmConfig)
   89.10          self.pid = None
   89.11          rtc_timeoffset = vmConfig['platform'].get('rtc_timeoffset')
   89.12 @@ -250,10 +250,6 @@ class ImageHandler:
   89.13      def parseDeviceModelArgs(self, vmConfig):
   89.14          ret = ["-domain-name", str(self.vm.info['name_label'])]
   89.15  
   89.16 -        # Tell QEMU how large the guest's memory allocation is
   89.17 -        # to help it when loading the initrd (if neccessary)
   89.18 -        ret += ["-m", str(self.getRequiredInitialReservation() / 1024)]
   89.19 -
   89.20          # Find RFB console device, and if it exists, make QEMU enable
   89.21          # the VNC console.
   89.22          if int(vmConfig['platform'].get('nographic', 0)) != 0:
   89.23 @@ -777,6 +773,10 @@ class HVMImageHandler(ImageHandler):
   89.24              ret.append("tap,vlan=%d,ifname=tap%d.%d,bridge=%s" %
   89.25                         (nics, self.vm.getDomid(), nics-1, bridge))
   89.26  
   89.27 +        if nics == 0:
   89.28 +            ret.append("-net")
   89.29 +            ret.append("none")
   89.30 +
   89.31          return ret
   89.32  
   89.33      def getDeviceModelArgs(self, restore = False):
    90.1 --- a/tools/python/xen/xend/server/pciif.py	Thu Aug 07 11:47:34 2008 +0900
    90.2 +++ b/tools/python/xen/xend/server/pciif.py	Thu Aug 07 11:57:34 2008 +0900
    90.3 @@ -375,17 +375,34 @@ class PciController(DevController):
    90.4                  raise VmError("pci: failed to locate device and "+
    90.5                          "parse it's resources - "+str(e))
    90.6              if (dev.dev_type == DEV_TYPE_PCIe_ENDPOINT) and not dev.pcie_flr:
    90.7 -                funcs = dev.find_all_the_multi_functions()
    90.8 -                for f in funcs:
    90.9 -                    if not f in pci_str_list:
   90.10 -                        err_msg = 'pci: % must be co-assigned to guest with %s'
   90.11 -                        raise VmError(err_msg % (f, dev.name))
   90.12 +                if dev.bus == 0:
   90.13 +                    # We cope with this case by using the Dstate transition
   90.14 +                    # method for now.
   90.15 +                    err_msg = 'pci: %s: it is on bus 0, but has no PCIe' +\
   90.16 +                        ' FLR Capability. Will try the Dstate transition'+\
   90.17 +                        ' method if available.'
   90.18 +                    log.warn(err_msg % dev.name)
   90.19 +                else:
   90.20 +                    funcs = dev.find_all_the_multi_functions()
   90.21 +                    for f in funcs:
   90.22 +                        if not f in pci_str_list:
   90.23 +                            (f_dom, f_bus, f_slot, f_func) = parse_pci_name(f)
   90.24 +                            f_pci_str = '0x%x,0x%x,0x%x,0x%x' % \
   90.25 +                                (f_dom, f_bus, f_slot, f_func)
   90.26 +                            # f has been assigned to other guest?
   90.27 +                            if xc.test_assign_device(0, f_pci_str) != 0:
   90.28 +                                err_msg = 'pci: %s must be co-assigned to' + \
   90.29 +                                    ' the same guest with %s'
   90.30 +                                raise VmError(err_msg % (f, dev.name))
   90.31              elif dev.dev_type == DEV_TYPE_PCI:
   90.32                  if dev.bus == 0:
   90.33                      if not dev.pci_af_flr:
   90.34 -                        err_msg = 'pci: %s is not assignable: it is on ' + \
   90.35 -                            'bus 0,  but lacks of FLR capability'
   90.36 -                        raise VmError(err_msg % dev.name)
   90.37 +                        # We cope with this case by using the Dstate transition
   90.38 +                        # method for now.
   90.39 +                        err_msg = 'pci: %s: it is on bus 0, but has no PCI' +\
   90.40 +                            ' Advanced Capabilities for FLR. Will try the'+\
   90.41 +                            ' Dstate transition method if available.'
   90.42 +                        log.warn(err_msg % dev.name)
   90.43                  else:
   90.44                      # All devices behind the uppermost PCI/PCI-X bridge must be\
   90.45                      # co-assigned to the same guest.
   90.46 @@ -395,8 +412,14 @@ class PciController(DevController):
   90.47  
   90.48                      for s in devs_str:
   90.49                          if not s in pci_str_list:
   90.50 -                            err_msg = 'pci: %s must be co-assigned to guest with %s'
   90.51 -                            raise VmError(err_msg % (s, dev.name))
   90.52 +                            (s_dom, s_bus, s_slot, s_func) = parse_pci_name(s)
   90.53 +                            s_pci_str = '0x%x,0x%x,0x%x,0x%x' % \
   90.54 +                                (s_dom, s_bus, s_slot, s_func)
   90.55 +                            # s has been assigned to other guest?
   90.56 +                            if xc.test_assign_device(0, s_pci_str) != 0:
   90.57 +                                err_msg = 'pci: %s must be co-assigned to the'+\
   90.58 +                                    ' same guest with %s'
   90.59 +                                raise VmError(err_msg % (s, dev.name))
   90.60  
   90.61          for (domain, bus, slot, func) in pci_dev_list:
   90.62              self.setupOneDevice(domain, bus, slot, func)
    91.1 --- a/tools/python/xen/xm/console.py	Thu Aug 07 11:47:34 2008 +0900
    91.2 +++ b/tools/python/xen/xm/console.py	Thu Aug 07 11:57:34 2008 +0900
    91.3 @@ -15,10 +15,69 @@
    91.4  # Copyright (C) 2005 XenSource Ltd
    91.5  #============================================================================
    91.6  
    91.7 +import xen.util.auxbin
    91.8 +import xen.lowlevel.xs
    91.9 +import os
   91.10 +import sys
   91.11 +import signal
   91.12 +from xen.util import utils
   91.13  
   91.14  XENCONSOLE = "xenconsole"
   91.15  
   91.16 -import xen.util.auxbin
   91.17 -
   91.18  def execConsole(domid):
   91.19      xen.util.auxbin.execute(XENCONSOLE, [str(domid)])
   91.20 +
   91.21 +
   91.22 +class OurXenstoreConnection:
   91.23 +    def __init__(self):
   91.24 +        self.handle = xen.lowlevel.xs.xs()
   91.25 +    def read_eventually(self, path):
   91.26 +        watch = None
   91.27 +        trans = None
   91.28 +        try:
   91.29 +            signal.alarm(10)
   91.30 +            watch = self.handle.watch(path, None)
   91.31 +            while True:
   91.32 +                result = self.handle.read('0', path)
   91.33 +                if result is not None:
   91.34 +                    signal.alarm(0)
   91.35 +                    return result
   91.36 +                self.handle.read_watch()
   91.37 +        finally:
   91.38 +            signal.alarm(0)
   91.39 +            if watch is not None: self.handle.unwatch(path, watch)
   91.40 +    def read_maybe(self, path):
   91.41 +        return self.handle.read('0', path)
   91.42 +
   91.43 +def runVncViewer(domid, do_autopass, do_daemonize=False):
   91.44 +    xs = OurXenstoreConnection()
   91.45 +    d = '/local/domain/%d/' % domid
   91.46 +    vnc_port = xs.read_eventually(d + 'console/vnc-port')
   91.47 +    vfb_backend = xs.read_maybe(d + 'device/vfb/0/backend')
   91.48 +    vnc_listen = None
   91.49 +    vnc_password = None
   91.50 +    vnc_password_tmpfile = None
   91.51 +    cmdl = ['vncviewer']
   91.52 +    if vfb_backend is not None:
   91.53 +        vnc_listen = xs.read_maybe(vfb_backend + '/vnclisten')
   91.54 +        if do_autopass:
   91.55 +            vnc_password = xs.read_maybe(vfb_backend + '/vncpasswd')
   91.56 +            if vnc_password is not None:
   91.57 +                cmdl.append('-autopass')
   91.58 +                vnc_password_tmpfile = os.tmpfile()
   91.59 +                print >>vnc_password_tmpfile, vnc_password
   91.60 +                vnc_password_tmpfile.seek(0)
   91.61 +                vnc_password_tmpfile.flush()
   91.62 +    if vnc_listen is None:
   91.63 +        vnc_listen = 'localhost'
   91.64 +    cmdl.append('%s:%d' % (vnc_listen, int(vnc_port) - 5900))
   91.65 +    if do_daemonize:
   91.66 +        pid = utils.daemonize('vncviewer', cmdl, vnc_password_tmpfile)
   91.67 +        if pid == 0:
   91.68 +            puts >>sys.stderr, 'failed to invoke vncviewer'
   91.69 +            os._exit(-1)
   91.70 +    else:
   91.71 +        print 'invoking ', ' '.join(cmdl)
   91.72 +        if vnc_password_tmpfile is not None:
   91.73 +            os.dup2(vnc_password_tmpfile.fileno(), 0)
   91.74 +        os.execvp('vncviewer', cmdl)
    92.1 --- a/tools/python/xen/xm/create.dtd	Thu Aug 07 11:47:34 2008 +0900
    92.2 +++ b/tools/python/xen/xm/create.dtd	Thu Aug 07 11:57:34 2008 +0900
    92.3 @@ -39,6 +39,7 @@
    92.4                   vbd*,
    92.5                   vif*,
    92.6                   vtpm*,
    92.7 +                 pci*,
    92.8                   console*,
    92.9                   platform*,
   92.10                   vcpu_param*,
   92.11 @@ -80,6 +81,13 @@
   92.12  <!ELEMENT vtpm   (name*)>
   92.13  <!ATTLIST vtpm   backend         CDATA #REQUIRED>
   92.14  
   92.15 +<!ELEMENT pci    EMPTY>
   92.16 +<!ATTLIST pci    domain          CDATA #REQUIRED
   92.17 +                 bus             CDATA #REQUIRED
   92.18 +                 slot            CDATA #REQUIRED
   92.19 +                 func            CDATA #REQUIRED
   92.20 +                 vslt            CDATA #IMPLIED>
   92.21 +
   92.22  <!ELEMENT console (other_config*)>
   92.23  <!ATTLIST console protocol       (vt100|rfb|rdp) #REQUIRED>
   92.24  
    93.1 --- a/tools/python/xen/xm/create.py	Thu Aug 07 11:47:34 2008 +0900
    93.2 +++ b/tools/python/xen/xm/create.py	Thu Aug 07 11:57:34 2008 +0900
    93.3 @@ -36,10 +36,12 @@ from xen.util import blkif
    93.4  from xen.util import vscsi_util
    93.5  import xen.util.xsm.xsm as security
    93.6  from xen.xm.main import serverType, SERVER_XEN_API, get_single_vm
    93.7 +from xen.util import utils
    93.8  
    93.9  from xen.xm.opts import *
   93.10  
   93.11  from main import server
   93.12 +from main import domain_name_to_domid
   93.13  import console
   93.14  
   93.15  
   93.16 @@ -118,6 +120,14 @@ gopts.opt('console_autoconnect', short='
   93.17            fn=set_true, default=0,
   93.18            use="Connect to the console after the domain is created.")
   93.19  
   93.20 +gopts.opt('vncviewer',
   93.21 +          fn=set_true, default=0,
   93.22 +          use="Connect to the VNC display after the domain is created.")
   93.23 +
   93.24 +gopts.opt('vncviewer-autopass',
   93.25 +          fn=set_true, default=0,
   93.26 +          use="Pass VNC password to viewer via stdin and -autopass.")
   93.27 +
   93.28  gopts.var('vncpasswd', val='NAME',
   93.29            fn=set_value, default=None,
   93.30            use="Password for VNC console on HVM domain.")
   93.31 @@ -128,7 +138,7 @@ gopts.var('vncviewer', val='no|yes',
   93.32             "The address of the vncviewer is passed to the domain on the "
   93.33             "kernel command line using 'VNC_SERVER=<host>:<port>'. The port "
   93.34             "used by vnc is 5500 + DISPLAY. A display value with a free port "
   93.35 -           "is chosen if possible.\nOnly valid when vnc=1.")
   93.36 +           "is chosen if possible.\nOnly valid when vnc=1.\nDEPRECATED")
   93.37  
   93.38  gopts.var('vncconsole', val='no|yes',
   93.39            fn=set_bool, default=None,
   93.40 @@ -1108,44 +1118,6 @@ def choose_vnc_display():
   93.41      return None
   93.42  vncpid = None
   93.43  
   93.44 -def daemonize(prog, args):
   93.45 -    """Runs a program as a daemon with the list of arguments.  Returns the PID
   93.46 -    of the daemonized program, or returns 0 on error.
   93.47 -    """
   93.48 -    r, w = os.pipe()
   93.49 -    pid = os.fork()
   93.50 -
   93.51 -    if pid == 0:
   93.52 -        os.close(r)
   93.53 -        w = os.fdopen(w, 'w')
   93.54 -        os.setsid()
   93.55 -        try:
   93.56 -            pid2 = os.fork()
   93.57 -        except:
   93.58 -            pid2 = None
   93.59 -        if pid2 == 0:
   93.60 -            os.chdir("/")
   93.61 -            for fd in range(0, 256):
   93.62 -                try:
   93.63 -                    os.close(fd)
   93.64 -                except:
   93.65 -                    pass
   93.66 -            os.open("/dev/null", os.O_RDWR)
   93.67 -            os.dup2(0, 1)
   93.68 -            os.dup2(0, 2)
   93.69 -            os.execvp(prog, args)
   93.70 -            os._exit(1)
   93.71 -        else:
   93.72 -            w.write(str(pid2 or 0))
   93.73 -            w.close()
   93.74 -            os._exit(0)
   93.75 -    os.close(w)
   93.76 -    r = os.fdopen(r)
   93.77 -    daemon_pid = int(r.read())
   93.78 -    r.close()
   93.79 -    os.waitpid(pid, 0)
   93.80 -    return daemon_pid
   93.81 -
   93.82  def spawn_vnc(display):
   93.83      """Spawns a vncviewer that listens on the specified display.  On success,
   93.84      returns the port that the vncviewer is listening on and sets the global
   93.85 @@ -1154,7 +1126,7 @@ def spawn_vnc(display):
   93.86      vncargs = (["vncviewer", "-log", "*:stdout:0",
   93.87              "-listen", "%d" % (VNC_BASE_PORT + display) ])
   93.88      global vncpid
   93.89 -    vncpid = daemonize("vncviewer", vncargs)
   93.90 +    vncpid = utils.daemonize("vncviewer", vncargs)
   93.91      if vncpid == 0:
   93.92          return 0
   93.93  
   93.94 @@ -1362,6 +1334,11 @@ def main(argv):
   93.95      elif not opts.is_xml:
   93.96          dom = make_domain(opts, config)
   93.97          
   93.98 +    if opts.vals.vncviewer:
   93.99 +        domid = domain_name_to_domid(sxp.child_value(config, 'name', -1))
  93.100 +        vncviewer_autopass = getattr(opts.vals,'vncviewer-autopass', False)
  93.101 +        console.runVncViewer(domid, vncviewer_autopass, True)
  93.102 +    
  93.103  def do_console(domain_name):
  93.104      cpid = os.fork() 
  93.105      if cpid != 0:
  93.106 @@ -1373,13 +1350,7 @@ def do_console(domain_name):
  93.107                  if os.WEXITSTATUS(rv) != 0:
  93.108                      sys.exit(os.WEXITSTATUS(rv))
  93.109              try:
  93.110 -                # Acquire the console of the created dom
  93.111 -                if serverType == SERVER_XEN_API:
  93.112 -                    domid = server.xenapi.VM.get_domid(
  93.113 -                               get_single_vm(domain_name))
  93.114 -                else:
  93.115 -                    dom = server.xend.domain(domain_name)
  93.116 -                    domid = int(sxp.child_value(dom, 'domid', '-1'))
  93.117 +                domid = domain_name_to_domid(domain_name)
  93.118                  console.execConsole(domid)
  93.119              except:
  93.120                  pass
    94.1 --- a/tools/python/xen/xm/main.py	Thu Aug 07 11:47:34 2008 +0900
    94.2 +++ b/tools/python/xen/xm/main.py	Thu Aug 07 11:57:34 2008 +0900
    94.3 @@ -64,6 +64,9 @@ import inspect
    94.4  from xen.xend import XendOptions
    94.5  xoptions = XendOptions.instance()
    94.6  
    94.7 +import signal
    94.8 +signal.signal(signal.SIGINT, signal.SIG_DFL)
    94.9 +
   94.10  # getopt.gnu_getopt is better, but only exists in Python 2.3+.  Use
   94.11  # getopt.getopt if gnu_getopt is not available.  This will mean that options
   94.12  # may only be specified before positional arguments.
   94.13 @@ -97,6 +100,8 @@ SUBCOMMAND_HELP = {
   94.14      
   94.15      'console'     : ('[-q|--quiet] <Domain>',
   94.16                       'Attach to <Domain>\'s console.'),
   94.17 +    'vncviewer'   : ('[--[vncviewer-]autopass] <Domain>',
   94.18 +                     'Attach to <Domain>\'s VNC server.'),
   94.19      'create'      : ('<ConfigFile> [options] [vars]',
   94.20                       'Create a domain based on <ConfigFile>.'),
   94.21      'destroy'     : ('<Domain>',
   94.22 @@ -243,6 +248,10 @@ SUBCOMMAND_OPTIONS = {
   94.23      'console': (
   94.24         ('-q', '--quiet', 'Do not print an error message if the domain does not exist'),
   94.25      ),
   94.26 +    'vncviewer': (
   94.27 +       ('', '--autopass', 'Pass VNC password to viewer via stdin and -autopass'),
   94.28 +       ('', '--vncviewer-autopass', '(consistency alias for --autopass)'),
   94.29 +    ),
   94.30      'dmesg': (
   94.31         ('-c', '--clear', 'Clear dmesg buffer as well as printing it'),
   94.32      ),
   94.33 @@ -260,6 +269,8 @@ SUBCOMMAND_OPTIONS = {
   94.34      'start': (
   94.35         ('-p', '--paused', 'Do not unpause domain after starting it'),
   94.36         ('-c', '--console_autoconnect', 'Connect to the console after the domain is created'),
   94.37 +       ('', '--vncviewer', 'Connect to display via VNC after the domain is created'),
   94.38 +       ('', '--vncviewer-autopass', 'Pass VNC password to viewer via stdin and -autopass'),
   94.39      ),
   94.40      'resume': (
   94.41         ('-p', '--paused', 'Do not unpause domain after resuming it'),
   94.42 @@ -277,6 +288,7 @@ SUBCOMMAND_OPTIONS = {
   94.43  
   94.44  common_commands = [
   94.45      "console",
   94.46 +    "vncviewer",
   94.47      "create",
   94.48      "new",
   94.49      "delete",
   94.50 @@ -304,6 +316,7 @@ common_commands = [
   94.51  
   94.52  domain_commands = [
   94.53      "console",
   94.54 +    "vncviewer",
   94.55      "create",
   94.56      "new",
   94.57      "delete",
   94.58 @@ -1185,14 +1198,20 @@ def xm_start(args):
   94.59  
   94.60      paused = False
   94.61      console_autoconnect = False
   94.62 +    vncviewer = False
   94.63 +    vncviewer_autopass = False
   94.64  
   94.65      try:
   94.66 -        (options, params) = getopt.gnu_getopt(args, 'cp', ['console_autoconnect','paused'])
   94.67 +        (options, params) = getopt.gnu_getopt(args, 'cp', ['console_autoconnect','paused','vncviewer','vncviewer-autopass'])
   94.68          for (k, v) in options:
   94.69              if k in ('-p', '--paused'):
   94.70                  paused = True
   94.71              if k in ('-c', '--console_autoconnect'):
   94.72                  console_autoconnect = True
   94.73 +            if k in ('--vncviewer'):
   94.74 +                vncviewer = True
   94.75 +            if k in ('--vncviewer-autopass'):
   94.76 +                vncviewer_autopass = True
   94.77  
   94.78          if len(params) != 1:
   94.79              raise OptionError("Expects 1 argument")
   94.80 @@ -1205,6 +1224,9 @@ def xm_start(args):
   94.81      if console_autoconnect:
   94.82          start_do_console(dom)
   94.83  
   94.84 +    if console_autoconnect:
   94.85 +        console.runVncViewer(domid, vncviewer_autopass, True)
   94.86 +
   94.87      try:
   94.88          if serverType == SERVER_XEN_API:
   94.89              server.xenapi.VM.start(get_single_vm(dom), paused)
   94.90 @@ -1783,6 +1805,40 @@ def xm_console(args):
   94.91      console.execConsole(domid)
   94.92  
   94.93  
   94.94 +def domain_name_to_domid(domain_name):
   94.95 +    if serverType == SERVER_XEN_API:
   94.96 +        domid = server.xenapi.VM.get_domid(
   94.97 +                   get_single_vm(domain_name))
   94.98 +    else:
   94.99 +        dom = server.xend.domain(domain_name)
  94.100 +        domid = int(sxp.child_value(dom, 'domid', '-1'))
  94.101 +    return domid
  94.102 +
  94.103 +def xm_vncviewer(args):
  94.104 +    autopass = False;
  94.105 +
  94.106 +    try:
  94.107 +        (options, params) = getopt.gnu_getopt(args, '', ['autopass','vncviewer-autopass'])
  94.108 +    except getopt.GetoptError, opterr:
  94.109 +        err(opterr)
  94.110 +        usage('vncviewer')
  94.111 +
  94.112 +    for (k, v) in options:
  94.113 +        if k in ['--autopass','--vncviewer-autopass']:
  94.114 +            autopass = True
  94.115 +        else:
  94.116 +            assert False
  94.117 +
  94.118 +    if len(params) != 1:
  94.119 +        err('No domain given (or several parameters specified)')
  94.120 +        usage('vncviewer')
  94.121 +
  94.122 +    dom = params[0]
  94.123 +    domid = domain_name_to_domid(dom)
  94.124 +
  94.125 +    console.runVncViewer(domid, autopass)
  94.126 +
  94.127 +
  94.128  def xm_uptime(args):
  94.129      short_mode = 0
  94.130  
  94.131 @@ -2102,7 +2158,23 @@ def xm_pci_list(args):
  94.132  
  94.133      dom = params[0]
  94.134  
  94.135 -    devs = server.xend.domain.getDeviceSxprs(dom, 'pci')
  94.136 +    devs = []
  94.137 +    if serverType == SERVER_XEN_API:
  94.138 +        for dpci_ref in server.xenapi.VM.get_DPCIs(get_single_vm(dom)):
  94.139 +            ppci_ref = server.xenapi.DPCI.get_PPCI(dpci_ref)
  94.140 +            ppci_record = server.xenapi.PPCI.get_record(ppci_ref)
  94.141 +            dev = {
  94.142 +                "domain":   "0x%04x" % int(ppci_record["domain"]),
  94.143 +                "bus":      "0x%02x" % int(ppci_record["bus"]),
  94.144 +                "slot":     "0x%02x" % int(ppci_record["slot"]),
  94.145 +                "func":     "0x%01x" % int(ppci_record["func"]),
  94.146 +                "vslt":     "0x%02x" % \
  94.147 +                            int(server.xenapi.DPCI.get_hotplug_slot(dpci_ref))
  94.148 +            }
  94.149 +            devs.append(dev)
  94.150 +
  94.151 +    else:
  94.152 +        devs = server.xend.domain.getDeviceSxprs(dom, 'pci')
  94.153  
  94.154      if len(devs) == 0:
  94.155          return
  94.156 @@ -2362,7 +2434,34 @@ def parse_pci_configuration(args, state)
  94.157  def xm_pci_attach(args):
  94.158      arg_check(args, 'pci-attach', 2, 3)
  94.159      (dom, pci) = parse_pci_configuration(args, 'Initialising')
  94.160 -    server.xend.domain.device_configure(dom, pci)
  94.161 +
  94.162 +    if serverType == SERVER_XEN_API:
  94.163 +
  94.164 +        pci_dev = sxp.children(pci, 'dev')[0]
  94.165 +        domain = int(sxp.child_value(pci_dev, 'domain'), 16)
  94.166 +        bus = int(sxp.child_value(pci_dev, 'bus'), 16)
  94.167 +        slot = int(sxp.child_value(pci_dev, 'slot'), 16)
  94.168 +        func = int(sxp.child_value(pci_dev, 'func'), 16)
  94.169 +        vslt = int(sxp.child_value(pci_dev, 'vslt'), 16)
  94.170 +        name = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func)
  94.171 +
  94.172 +        target_ref = None
  94.173 +        for ppci_ref in server.xenapi.PPCI.get_all():
  94.174 +            if name == server.xenapi.PPCI.get_name(ppci_ref):
  94.175 +                target_ref = ppci_ref
  94.176 +                break
  94.177 +        if target_ref is None:
  94.178 +            raise OptionError("Device %s not found" % name)
  94.179 +
  94.180 +        dpci_record = {
  94.181 +            "VM":           get_single_vm(dom),
  94.182 +            "PPCI":         target_ref,
  94.183 +            "hotplug_slot": vslt
  94.184 +        }
  94.185 +        server.xenapi.DPCI.create(dpci_record)
  94.186 +
  94.187 +    else:
  94.188 +        server.xend.domain.device_configure(dom, pci)
  94.189  
  94.190  def xm_scsi_attach(args):
  94.191      xenapi_unsupported()
  94.192 @@ -2462,7 +2561,29 @@ def xm_network_detach(args):
  94.193  def xm_pci_detach(args):
  94.194      arg_check(args, 'pci-detach', 2)
  94.195      (dom, pci) = parse_pci_configuration(args, 'Closing')
  94.196 -    server.xend.domain.device_configure(dom, pci)
  94.197 +
  94.198 +    if serverType == SERVER_XEN_API:
  94.199 +
  94.200 +        pci_dev = sxp.children(pci, 'dev')[0]
  94.201 +        domain = int(sxp.child_value(pci_dev, 'domain'), 16)
  94.202 +        bus = int(sxp.child_value(pci_dev, 'bus'), 16)
  94.203 +        slot = int(sxp.child_value(pci_dev, 'slot'), 16)
  94.204 +        func = int(sxp.child_value(pci_dev, 'func'), 16)
  94.205 +        vslt = int(sxp.child_value(pci_dev, 'vslt'), 16)
  94.206 +        name = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func)
  94.207 +
  94.208 +        target_ref = None
  94.209 +        for dpci_ref in server.xenapi.VM.get_DPCIs(get_single_vm(dom)):
  94.210 +            ppci_ref = server.xenapi.DPCI.get_PPCI(dpci_ref)
  94.211 +            if name == server.xenapi.PPCI.get_name(ppci_ref):
  94.212 +                target_ref = ppci_ref
  94.213 +                server.xenapi.DPCI.destroy(dpci_ref)
  94.214 +                break
  94.215 +        if target_ref is None:
  94.216 +            raise OptionError("Device %s not assigned" % name)
  94.217 +
  94.218 +    else:
  94.219 +        server.xend.domain.device_configure(dom, pci)
  94.220  
  94.221  def xm_scsi_detach(args):
  94.222      xenapi_unsupported()
  94.223 @@ -2617,6 +2738,7 @@ commands = {
  94.224      "event-monitor": xm_event_monitor,
  94.225      # console commands
  94.226      "console": xm_console,
  94.227 +    "vncviewer": xm_vncviewer,
  94.228      # xenstat commands
  94.229      "top": xm_top,
  94.230      # domain commands
    95.1 --- a/tools/python/xen/xm/shutdown.py	Thu Aug 07 11:47:34 2008 +0900
    95.2 +++ b/tools/python/xen/xm/shutdown.py	Thu Aug 07 11:57:34 2008 +0900
    95.3 @@ -144,9 +144,10 @@ def main_all(opts, args):
    95.4  def main_dom(opts, args):
    95.5      if len(args) == 0: opts.err('No domain parameter given')
    95.6      if len(args) >  1: opts.err('No multiple domain parameters allowed')
    95.7 -    dom = sxp.child_value(server.xend.domain(args[0]), 'name')
    95.8      if serverType == SERVER_XEN_API:
    95.9 -        dom = get_single_vm(dom)
   95.10 +        dom = get_single_vm(args[0])
   95.11 +    else:
   95.12 +        dom = sxp.child_value(server.xend.domain(args[0]), 'name')
   95.13      mode = shutdown_mode(opts)  
   95.14      shutdown(opts, [ dom ], mode, opts.vals.wait)
   95.15      
    96.1 --- a/tools/python/xen/xm/xenapi_create.py	Thu Aug 07 11:47:34 2008 +0900
    96.2 +++ b/tools/python/xen/xm/xenapi_create.py	Thu Aug 07 11:57:34 2008 +0900
    96.3 @@ -369,6 +369,12 @@ class xenapi_create:
    96.4  
    96.5              self.create_consoles(vm_ref, consoles)
    96.6  
    96.7 +            # Now create pcis
    96.8 +
    96.9 +            pcis = vm.getElementsByTagName("pci")
   96.10 +
   96.11 +            self.create_pcis(vm_ref, pcis)
   96.12 +
   96.13              return vm_ref
   96.14          except:
   96.15              server.xenapi.VM.destroy(vm_ref)
   96.16 @@ -389,7 +395,7 @@ class xenapi_create:
   96.17              "device":
   96.18                  vbd.attributes["device"].value,
   96.19              "bootable":
   96.20 -                vbd.attributes["bootable"].value == "True",
   96.21 +                vbd.attributes["bootable"].value == "1",
   96.22              "mode":
   96.23                  vbd.attributes["mode"].value,
   96.24              "type":
   96.25 @@ -493,6 +499,39 @@ class xenapi_create:
   96.26  
   96.27          return server.xenapi.console.create(console_record)
   96.28  
   96.29 +    def create_pcis(self, vm_ref, pcis):
   96.30 +        log(DEBUG, "create_pcis")
   96.31 +        return map(lambda pci: self.create_pci(vm_ref, pci), pcis)
   96.32 +
   96.33 +    def create_pci(self, vm_ref, pci):
   96.34 +        log(DEBUG, "create_pci")
   96.35 +
   96.36 +        domain = int(pci.attributes["domain"].value, 16)
   96.37 +        bus = int(pci.attributes["bus"].value, 16)
   96.38 +        slot = int(pci.attributes["slot"].value, 16)
   96.39 +        func = int(pci.attributes["func"].value, 16)
   96.40 +        name = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func)
   96.41 +
   96.42 +        target_ref = None
   96.43 +        for ppci_ref in server.xenapi.PPCI.get_all():
   96.44 +            if name == server.xenapi.PPCI.get_name(ppci_ref):
   96.45 +                target_ref = ppci_ref
   96.46 +                break
   96.47 +        if target_ref is None:
   96.48 +            log(DEBUG, "create_pci: pci device not found")
   96.49 +            return None
   96.50 +
   96.51 +        dpci_record = {
   96.52 +            "VM":
   96.53 +                vm_ref,
   96.54 +            "PPCI":
   96.55 +                target_ref,
   96.56 +            "hotplug_slot":
   96.57 +                int(pci.attributes["func"].value, 16)
   96.58 +        }
   96.59 +
   96.60 +        return server.xenapi.DPCI.create(dpci_record)
   96.61 +
   96.62  def get_child_by_name(exp, childname, default = None):
   96.63      try:
   96.64          return [child for child in sxp.children(exp)
   96.65 @@ -521,6 +560,9 @@ class sxp2xml:
   96.66          vfbs_sxp = map(lambda x: x[1], [device for device in devices
   96.67                                          if device[1][0] == "vfb"])
   96.68  
   96.69 +        pcis_sxp = map(lambda x: x[1], [device for device in devices
   96.70 +                                        if device[1][0] == "pci"])
   96.71 +
   96.72          # Create XML Document
   96.73          
   96.74          impl = getDOMImplementation()
   96.75 @@ -597,13 +639,15 @@ class sxp2xml:
   96.76              pv = document.createElement("pv")
   96.77              pv.attributes["kernel"] \
   96.78                  = get_child_by_name(image, "kernel", "")
   96.79 -            pv.attributes["bootloader"] = ""
   96.80 +            pv.attributes["bootloader"] \
   96.81 +                = get_child_by_name(config, "bootloader", "")
   96.82              pv.attributes["ramdisk"] \
   96.83                  = get_child_by_name(image, "ramdisk", "")
   96.84              pv.attributes["args"] \
   96.85                  = "root=" + get_child_by_name(image, "root", "") \
   96.86                  + " " + get_child_by_name(image, "args", "")
   96.87 -            pv.attributes["bootloader_args"] = ""
   96.88 +            pv.attributes["bootloader_args"] \
   96.89 +                = get_child_by_name(config, "bootloader_args","")
   96.90  
   96.91              vm.appendChild(pv)
   96.92          elif image[0] == "hvm":
   96.93 @@ -654,6 +698,12 @@ class sxp2xml:
   96.94  
   96.95          map(vm.appendChild, vtpms)
   96.96  
   96.97 +        # And now the pcis
   96.98 +
   96.99 +        pcis = self.extract_pcis(pcis_sxp, document)
  96.100 +
  96.101 +        map(vm.appendChild, pcis)
  96.102 +
  96.103          # Last but not least the consoles...
  96.104  
  96.105          consoles = self.extract_consoles(image, document)
  96.106 @@ -821,7 +871,28 @@ class sxp2xml:
  96.107  
  96.108          return vfb
  96.109  
  96.110 -    _eths = -1
  96.111 +    def extract_pcis(self, pcis_sxp, document):
  96.112 +
  96.113 +        pcis = []
  96.114 +
  96.115 +        for pci_sxp in pcis_sxp:
  96.116 +            for dev_sxp in sxp.children(pci_sxp, "dev"):
  96.117 +                pci = document.createElement("pci")
  96.118 +
  96.119 +                pci.attributes["domain"] \
  96.120 +                    = get_child_by_name(dev_sxp, "domain", "0")
  96.121 +                pci.attributes["bus"] \
  96.122 +                    = get_child_by_name(dev_sxp, "bus", "0")
  96.123 +                pci.attributes["slot"] \
  96.124 +                    = get_child_by_name(dev_sxp, "slot", "0")
  96.125 +                pci.attributes["func"] \
  96.126 +                    = get_child_by_name(dev_sxp, "func", "0")
  96.127 +                pci.attributes["vslt"] \
  96.128 +                    = get_child_by_name(dev_sxp, "vslt", "0")
  96.129 +
  96.130 +                pcis.append(pci)
  96.131 +
  96.132 +        return pcis
  96.133  
  96.134      def mk_other_config(self, key, value, document):
  96.135          other_config = document.createElement("other_config")
  96.136 @@ -914,6 +985,8 @@ class sxp2xml:
  96.137   
  96.138          return platform_configs
  96.139      
  96.140 +    _eths = -1
  96.141 +
  96.142      def getFreshEthDevice(self):
  96.143          self._eths += 1
  96.144          return "eth%i" % self._eths
    97.1 --- a/tools/xenmon/Makefile	Thu Aug 07 11:47:34 2008 +0900
    97.2 +++ b/tools/xenmon/Makefile	Thu Aug 07 11:57:34 2008 +0900
    97.3 @@ -33,6 +33,8 @@ install: build
    97.4  	$(INSTALL_PROG) xenbaked $(DESTDIR)$(SBINDIR)/xenbaked
    97.5  	$(INSTALL_PROG) xentrace_setmask  $(DESTDIR)$(SBINDIR)/xentrace_setmask
    97.6  	$(INSTALL_PROG) xenmon.py  $(DESTDIR)$(SBINDIR)/xenmon.py
    97.7 +	$(INSTALL_DIR) $(DESTDIR)$(DOCDIR)
    97.8 +	$(INSTALL_DATA) README $(DESTDIR)$(DOCDIR)/README.xenmon
    97.9  
   97.10  .PHONY: clean
   97.11  clean:
    98.1 --- a/tools/xenstat/libxenstat/Makefile	Thu Aug 07 11:47:34 2008 +0900
    98.2 +++ b/tools/xenstat/libxenstat/Makefile	Thu Aug 07 11:57:34 2008 +0900
    98.3 @@ -15,7 +15,7 @@
    98.4  XEN_ROOT=../../..
    98.5  include $(XEN_ROOT)/tools/Rules.mk
    98.6  
    98.7 -prefix=/usr
    98.8 +prefix=$(PREFIX)
    98.9  includedir=$(prefix)/include
   98.10  libdir=$(prefix)/lib
   98.11  
    99.1 --- a/tools/xenstat/libxenstat/src/xenstat.c	Thu Aug 07 11:47:34 2008 +0900
    99.2 +++ b/tools/xenstat/libxenstat/src/xenstat.c	Thu Aug 07 11:57:34 2008 +0900
    99.3 @@ -109,7 +109,7 @@ xenstat_handle *xenstat_init(void)
    99.4  
    99.5  	handle->xshandle = xs_daemon_open_readonly(); /* open handle to xenstore*/
    99.6  	if (handle->xshandle == NULL) {
    99.7 -		perror("unable to open xenstore\n");
    99.8 +		perror("unable to open xenstore");
    99.9  		xc_interface_close(handle->xc_handle);
   99.10  		free(handle);
   99.11  		return NULL;
   100.1 --- a/unmodified_drivers/linux-2.6/platform-pci/machine_reboot.c	Thu Aug 07 11:47:34 2008 +0900
   100.2 +++ b/unmodified_drivers/linux-2.6/platform-pci/machine_reboot.c	Thu Aug 07 11:57:34 2008 +0900
   100.3 @@ -71,7 +71,7 @@ static int bp_suspend(void)
   100.4  	return suspend_cancelled;
   100.5  }
   100.6  
   100.7 -int __xen_suspend(int fast_suspend, void (*resume_notifier)(void))
   100.8 +int __xen_suspend(int fast_suspend, void (*resume_notifier)(int))
   100.9  {
  100.10  	int err, suspend_cancelled, nr_cpus;
  100.11  	struct ap_suspend_info info;
  100.12 @@ -101,7 +101,7 @@ int __xen_suspend(int fast_suspend, void
  100.13  
  100.14  	local_irq_disable();
  100.15  	suspend_cancelled = bp_suspend();
  100.16 -	resume_notifier();
  100.17 +	resume_notifier(suspend_cancelled);
  100.18  	local_irq_enable();
  100.19  
  100.20  	smp_mb();
   101.1 --- a/xen/Makefile	Thu Aug 07 11:47:34 2008 +0900
   101.2 +++ b/xen/Makefile	Thu Aug 07 11:57:34 2008 +0900
   101.3 @@ -1,8 +1,8 @@
   101.4  # This is the correct place to edit the build version.
   101.5  # All other places this is stored (eg. compile.h) should be autogenerated.
   101.6 -export XEN_VERSION       = 3
   101.7 -export XEN_SUBVERSION    = 3
   101.8 -export XEN_EXTRAVERSION ?= -unstable$(XEN_VENDORVERSION)
   101.9 +export XEN_VERSION       = 4
  101.10 +export XEN_SUBVERSION    = 0
  101.11 +export XEN_EXTRAVERSION ?= .0-rc3-pre$(XEN_VENDORVERSION)
  101.12  export XEN_FULLVERSION   = $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION)
  101.13  -include xen-version
  101.14  
   102.1 --- a/xen/arch/ia64/xen/domain.c	Thu Aug 07 11:47:34 2008 +0900
   102.2 +++ b/xen/arch/ia64/xen/domain.c	Thu Aug 07 11:57:34 2008 +0900
   102.3 @@ -2212,8 +2212,9 @@ int __init construct_dom0(struct domain 
   102.4  	return 0;
   102.5  }
   102.6  
   102.7 -void machine_restart(void)
   102.8 +void machine_restart(unsigned int delay_millisecs)
   102.9  {
  102.10 +	mdelay(delay_millisecs);
  102.11  	console_start_sync();
  102.12  	if (running_on_sim)
  102.13  		printk ("machine_restart called.  spinning...\n");
   103.1 --- a/xen/arch/ia64/xen/irq.c	Thu Aug 07 11:47:34 2008 +0900
   103.2 +++ b/xen/arch/ia64/xen/irq.c	Thu Aug 07 11:57:34 2008 +0900
   103.3 @@ -459,7 +459,7 @@ int pirq_guest_bind(struct vcpu *v, int 
   103.4      return rc;
   103.5  }
   103.6  
   103.7 -int pirq_guest_unbind(struct domain *d, int irq)
   103.8 +void pirq_guest_unbind(struct domain *d, int irq)
   103.9  {
  103.10      irq_desc_t         *desc = &irq_desc[irq];
  103.11      irq_guest_action_t *action;
  103.12 @@ -493,7 +493,6 @@ int pirq_guest_unbind(struct domain *d, 
  103.13      }
  103.14  
  103.15      spin_unlock_irqrestore(&desc->lock, flags);    
  103.16 -    return 0;
  103.17  }
  103.18  
  103.19  void
   104.1 --- a/xen/arch/x86/acpi/cpufreq/utility.c	Thu Aug 07 11:47:34 2008 +0900
   104.2 +++ b/xen/arch/x86/acpi/cpufreq/utility.c	Thu Aug 07 11:57:34 2008 +0900
   104.3 @@ -296,12 +296,11 @@ void cpufreq_suspend(void)
   104.4  {
   104.5      int cpu;
   104.6  
   104.7 -    /* to protect the case when Px was controlled by dom0-kernel */
   104.8 -    /* or when CPU_FREQ not set in which case ACPI Px objects not parsed */
   104.9 +    /* to protect the case when Px was not controlled by xen */
  104.10      for_each_online_cpu(cpu) {
  104.11          struct processor_performance *perf = &processor_pminfo[cpu].perf;
  104.12  
  104.13 -        if (!perf->init)
  104.14 +        if (!(perf->init & XEN_PX_INIT))
  104.15              return;
  104.16      }
  104.17  
  104.18 @@ -316,14 +315,13 @@ int cpufreq_resume(void)
  104.19  {
  104.20      int cpu, ret = 0;
  104.21  
  104.22 -    /* 1. to protect the case when Px was controlled by dom0-kernel */
  104.23 -    /* or when CPU_FREQ not set in which case ACPI Px objects not parsed */
  104.24 +    /* 1. to protect the case when Px was not controlled by xen */
  104.25      /* 2. set state and resume flag to sync cpu to right state and freq */
  104.26      for_each_online_cpu(cpu) {
  104.27          struct processor_performance *perf = &processor_pminfo[cpu].perf;
  104.28          struct cpufreq_policy *policy = &xen_px_policy[cpu];
  104.29  
  104.30 -        if (!perf->init)
  104.31 +        if (!(perf->init & XEN_PX_INIT))
  104.32              goto err;
  104.33          perf->state = 0;
  104.34          policy->resume = 1;
   105.1 --- a/xen/arch/x86/acpi/pmstat.c	Thu Aug 07 11:47:34 2008 +0900
   105.2 +++ b/xen/arch/x86/acpi/pmstat.c	Thu Aug 07 11:57:34 2008 +0900
   105.3 @@ -52,9 +52,9 @@ int do_get_pm_info(struct xen_sysctl_get
   105.4      struct pm_px *pxpt = &px_statistic_data[op->cpuid];
   105.5      struct processor_pminfo *pmpt = &processor_pminfo[op->cpuid];
   105.6  
   105.7 -    /* to protect the case when Px was controlled by dom0-kernel */
   105.8 -    /* or when CPU_FREQ not set in which case ACPI Px objects not parsed */
   105.9 -    if ( !pmpt->perf.init && (op->type & PMSTAT_CATEGORY_MASK) == PMSTAT_PX )
  105.10 +    /* to protect the case when Px was not controlled by xen */
  105.11 +    if ( (!(pmpt->perf.init & XEN_PX_INIT)) && 
  105.12 +        (op->type & PMSTAT_CATEGORY_MASK) == PMSTAT_PX )
  105.13          return -EINVAL;
  105.14  
  105.15      if ( !cpu_online(op->cpuid) )
   106.1 --- a/xen/arch/x86/domain.c	Thu Aug 07 11:47:34 2008 +0900
   106.2 +++ b/xen/arch/x86/domain.c	Thu Aug 07 11:57:34 2008 +0900
   106.3 @@ -1811,7 +1811,6 @@ int domain_relinquish_resources(struct d
   106.4          if ( ret )
   106.5              return ret;
   106.6  #endif
   106.7 -        WARN_ON(d->xenheap_pages);
   106.8          break;
   106.9  
  106.10      default:
   107.1 --- a/xen/arch/x86/domain_build.c	Thu Aug 07 11:47:34 2008 +0900
   107.2 +++ b/xen/arch/x86/domain_build.c	Thu Aug 07 11:57:34 2008 +0900
   107.3 @@ -757,6 +757,7 @@ int __init construct_dom0(
   107.4      si->shared_info = virt_to_maddr(d->shared_info);
   107.5  
   107.6      si->flags        = SIF_PRIVILEGED | SIF_INITDOMAIN;
   107.7 +    si->flags       |= (xen_processor_pmbits << 8) & SIF_PM_MASK;
   107.8      si->pt_base      = vpt_start + 2 * PAGE_SIZE * !!is_pv_32on64_domain(d);
   107.9      si->nr_pt_frames = nr_pt_pages;
  107.10      si->mfn_list     = vphysmap_start;
   108.1 --- a/xen/arch/x86/domctl.c	Thu Aug 07 11:47:34 2008 +0900
   108.2 +++ b/xen/arch/x86/domctl.c	Thu Aug 07 11:57:34 2008 +0900
   108.3 @@ -661,6 +661,7 @@ long arch_do_domctl(
   108.4          if ( !iommu_pv_enabled && !is_hvm_domain(d) )
   108.5          {
   108.6              ret = -ENOSYS;
   108.7 +            put_domain(d);
   108.8              break;
   108.9          }
  108.10  
  108.11 @@ -669,12 +670,16 @@ long arch_do_domctl(
  108.12              gdprintk(XENLOG_ERR, "XEN_DOMCTL_assign_device: "
  108.13                       "%x:%x:%x already assigned, or non-existent\n",
  108.14                       bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
  108.15 +            put_domain(d);
  108.16              break;
  108.17          }
  108.18  
  108.19          ret = assign_device(d, bus, devfn);
  108.20 -        gdprintk(XENLOG_INFO, "XEN_DOMCTL_assign_device: bdf = %x:%x:%x\n",
  108.21 -                 bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
  108.22 +        if ( ret )
  108.23 +            gdprintk(XENLOG_ERR, "XEN_DOMCTL_assign_device: "
  108.24 +                     "assign device (%x:%x:%x) failed\n",
  108.25 +                     bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
  108.26 +
  108.27          put_domain(d);
  108.28      }
  108.29      break;
  108.30 @@ -701,11 +706,15 @@ long arch_do_domctl(
  108.31          if ( !iommu_pv_enabled && !is_hvm_domain(d) )
  108.32          {
  108.33              ret = -ENOSYS;
  108.34 +            put_domain(d);
  108.35              break;
  108.36          }
  108.37  
  108.38          if ( !device_assigned(bus, devfn) )
  108.39 +        {
  108.40 +            put_domain(d);
  108.41              break;
  108.42 +        }
  108.43  
  108.44          ret = 0;
  108.45          deassign_device(d, bus, devfn);
   109.1 --- a/xen/arch/x86/hvm/io.c	Thu Aug 07 11:47:34 2008 +0900
   109.2 +++ b/xen/arch/x86/hvm/io.c	Thu Aug 07 11:57:34 2008 +0900
   109.3 @@ -284,7 +284,7 @@ void dpci_ioport_write(uint32_t mport, i
   109.4          data = p->data;
   109.5          if ( p->data_is_ptr )
   109.6              (void)hvm_copy_from_guest_phys(
   109.7 -                &data, p->data + (sign * i & p->size), p->size);
   109.8 +                &data, p->data + (sign * i * p->size), p->size);
   109.9  
  109.10          switch ( p->size )
  109.11          {
   110.1 --- a/xen/arch/x86/hvm/stdvga.c	Thu Aug 07 11:47:34 2008 +0900
   110.2 +++ b/xen/arch/x86/hvm/stdvga.c	Thu Aug 07 11:57:34 2008 +0900
   110.3 @@ -33,6 +33,10 @@
   110.4  #include <xen/domain_page.h>
   110.5  #include <asm/hvm/support.h>
   110.6  #include <xen/numa.h>
   110.7 +#include <xen/paging.h>
   110.8 +
   110.9 +#define VGA_MEM_BASE 0xa0000
  110.10 +#define VGA_MEM_SIZE 0x20000
  110.11  
  110.12  #define PAT(x) (x)
  110.13  static const uint32_t mask16[16] = {
  110.14 @@ -464,6 +468,7 @@ static int mmio_move(struct hvm_hw_stdvg
  110.15  {
  110.16      int i;
  110.17      int sign = p->df ? -1 : 1;
  110.18 +    p2m_type_t p2mt;
  110.19  
  110.20      if ( p->data_is_ptr )
  110.21      {
  110.22 @@ -473,7 +478,19 @@ static int mmio_move(struct hvm_hw_stdvg
  110.23              for ( i = 0; i < p->count; i++ ) 
  110.24              {
  110.25                  tmp = stdvga_mem_read(addr, p->size);
  110.26 -                hvm_copy_to_guest_phys(data, &tmp, p->size);
  110.27 +                if ( hvm_copy_to_guest_phys(data, &tmp, p->size) ==
  110.28 +                     HVMCOPY_bad_gfn_to_mfn )
  110.29 +                {
  110.30 +                    (void)gfn_to_mfn_current(data >> PAGE_SHIFT, &p2mt);
  110.31 +                    /*
  110.32 +                     * The only case we handle is vga_mem <-> vga_mem.
  110.33 +                     * Anything else disables caching and leaves it to qemu-dm.
  110.34 +                     */
  110.35 +                    if ( (p2mt != p2m_mmio_dm) || (data < VGA_MEM_BASE) ||
  110.36 +                         ((data + p->size) > (VGA_MEM_BASE + VGA_MEM_SIZE)) )
  110.37 +                        return 0;
  110.38 +                    stdvga_mem_write(data, tmp, p->size);
  110.39 +                }
  110.40                  data += sign * p->size;
  110.41                  addr += sign * p->size;
  110.42              }
  110.43 @@ -483,7 +500,15 @@ static int mmio_move(struct hvm_hw_stdvg
  110.44              uint32_t addr = p->addr, data = p->data, tmp;
  110.45              for ( i = 0; i < p->count; i++ )
  110.46              {
  110.47 -                hvm_copy_from_guest_phys(&tmp, data, p->size);
  110.48 +                if ( hvm_copy_from_guest_phys(&tmp, data, p->size) ==
  110.49 +                     HVMCOPY_bad_gfn_to_mfn )
  110.50 +                {
  110.51 +                    (void)gfn_to_mfn_current(data >> PAGE_SHIFT, &p2mt);
  110.52 +                    if ( (p2mt != p2m_mmio_dm) || (data < VGA_MEM_BASE) ||
  110.53 +                         ((data + p->size) > (VGA_MEM_BASE + VGA_MEM_SIZE)) )
  110.54 +                        return 0;
  110.55 +                    tmp = stdvga_mem_read(data, p->size);
  110.56 +                }
  110.57                  stdvga_mem_write(addr, tmp, p->size);
  110.58                  data += sign * p->size;
  110.59                  addr += sign * p->size;
  110.60 @@ -536,7 +561,8 @@ static int stdvga_intercept_mmio(ioreq_t
  110.61          {
  110.62          case IOREQ_TYPE_COPY:
  110.63              buf = mmio_move(s, p);
  110.64 -            break;
  110.65 +            if ( buf )
  110.66 +                break;
  110.67          default:
  110.68              gdprintk(XENLOG_WARNING, "unsupported mmio request type:%d "
  110.69                       "addr:0x%04x data:0x%04x size:%d count:%d state:%d "
  110.70 @@ -588,7 +614,7 @@ void stdvga_init(struct domain *d)
  110.71          register_portio_handler(d, 0x3ce, 2, stdvga_intercept_pio);
  110.72          /* MMIO. */
  110.73          register_buffered_io_handler(
  110.74 -            d, 0xa0000, 0x20000, stdvga_intercept_mmio);
  110.75 +            d, VGA_MEM_BASE, VGA_MEM_SIZE, stdvga_intercept_mmio);
  110.76      }
  110.77  }
  110.78  
   111.1 --- a/xen/arch/x86/hvm/svm/svm.c	Thu Aug 07 11:47:34 2008 +0900
   111.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Thu Aug 07 11:57:34 2008 +0900
   111.3 @@ -874,9 +874,12 @@ static void svm_do_nested_pgfault(paddr_
   111.4      mfn_t mfn;
   111.5      unsigned long gfn = gpa >> PAGE_SHIFT;
   111.6  
   111.7 -    /* If this GFN is emulated MMIO, pass the fault to the mmio handler */
   111.8 +    /*
   111.9 +     * If this GFN is emulated MMIO or marked as read-only, pass the fault
  111.10 +     * to the mmio handler.
  111.11 +     */
  111.12      mfn = gfn_to_mfn_current(gfn, &p2mt);
  111.13 -    if ( p2mt == p2m_mmio_dm )
  111.14 +    if ( (p2mt == p2m_mmio_dm) || (p2mt == p2m_ram_ro) )
  111.15      {
  111.16          if ( !handle_mmio() )
  111.17              hvm_inject_exception(TRAP_gp_fault, 0, 0);
   112.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Thu Aug 07 11:47:34 2008 +0900
   112.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Thu Aug 07 11:57:34 2008 +0900
   112.3 @@ -1971,7 +1971,7 @@ static void ept_handle_violation(unsigne
   112.4      }
   112.5  
   112.6      mfn = gfn_to_mfn(d, gfn, &t);
   112.7 -    if ( p2m_is_ram(t) && paging_mode_log_dirty(d) )
   112.8 +    if ( (t != p2m_ram_ro) && p2m_is_ram(t) && paging_mode_log_dirty(d) )
   112.9      {
  112.10          paging_mark_dirty(d, mfn_x(mfn));
  112.11          p2m_change_type(d, gfn, p2m_ram_logdirty, p2m_ram_rw);
   113.1 --- a/xen/arch/x86/io_apic.c	Thu Aug 07 11:47:34 2008 +0900
   113.2 +++ b/xen/arch/x86/io_apic.c	Thu Aug 07 11:57:34 2008 +0900
   113.3 @@ -45,12 +45,12 @@
   113.4  int (*ioapic_renumber_irq)(int ioapic, int irq);
   113.5  atomic_t irq_mis_count;
   113.6  
   113.7 -int msi_irq_enable = 0;
   113.8 -boolean_param("msi_irq_enable", msi_irq_enable);
   113.9 +int msi_enable = 0;
  113.10 +boolean_param("msi", msi_enable);
  113.11  
  113.12  int domain_irq_to_vector(struct domain *d, int irq)
  113.13  {
  113.14 -    if ( !msi_irq_enable )
  113.15 +    if ( !msi_enable )
  113.16          return irq_to_vector(irq);
  113.17      else
  113.18          return d->arch.pirq_vector[irq];
  113.19 @@ -58,7 +58,7 @@ int domain_irq_to_vector(struct domain *
  113.20  
  113.21  int domain_vector_to_irq(struct domain *d, int vector)
  113.22  {
  113.23 -    if ( !msi_irq_enable )
  113.24 +    if ( !msi_enable )
  113.25          return vector_to_irq(vector);
  113.26      else
  113.27          return d->arch.vector_pirq[vector];
   114.1 --- a/xen/arch/x86/irq.c	Thu Aug 07 11:47:34 2008 +0900
   114.2 +++ b/xen/arch/x86/irq.c	Thu Aug 07 11:57:34 2008 +0900
   114.3 @@ -573,7 +573,7 @@ int pirq_guest_bind(struct vcpu *v, int 
   114.4      return rc;
   114.5  }
   114.6  
   114.7 -int pirq_guest_unbind(struct domain *d, int irq)
   114.8 +void pirq_guest_unbind(struct domain *d, int irq)
   114.9  {
  114.10      unsigned int        vector;
  114.11      irq_desc_t         *desc;
  114.12 @@ -660,7 +660,6 @@ int pirq_guest_unbind(struct domain *d, 
  114.13  
  114.14   out:
  114.15      spin_unlock_irqrestore(&desc->lock, flags);    
  114.16 -    return 0;
  114.17  }
  114.18  
  114.19  extern void dump_ioapic_irq_info(void);
   115.1 --- a/xen/arch/x86/mm.c	Thu Aug 07 11:47:34 2008 +0900
   115.2 +++ b/xen/arch/x86/mm.c	Thu Aug 07 11:57:34 2008 +0900
   115.3 @@ -1138,8 +1138,10 @@ static int alloc_l2_table(struct page_in
   115.4  
   115.5      for ( i = 0; i < L2_PAGETABLE_ENTRIES; i++ )
   115.6      {
   115.7 -        if ( is_guest_l2_slot(d, type, i) &&
   115.8 -             unlikely(!get_page_from_l2e(pl2e[i], pfn, d)) )
   115.9 +        if ( !is_guest_l2_slot(d, type, i) )
  115.10 +            continue;
  115.11 +
  115.12 +        if ( unlikely(!get_page_from_l2e(pl2e[i], pfn, d)) )
  115.13              goto fail;
  115.14          
  115.15          adjust_guest_l2e(pl2e[i], d);
  115.16 @@ -1206,8 +1208,9 @@ static int alloc_l3_table(struct page_in
  115.17                                                  d) )
  115.18                  goto fail;
  115.19          }
  115.20 -        else if ( is_guest_l3_slot(i) &&
  115.21 -                  unlikely(!get_page_from_l3e(pl3e[i], pfn, d)) )
  115.22 +        else if ( !is_guest_l3_slot(i) )
  115.23 +            continue;
  115.24 +        else if ( unlikely(!get_page_from_l3e(pl3e[i], pfn, d)) )
  115.25              goto fail;
  115.26  
  115.27          adjust_guest_l3e(pl3e[i], d);
  115.28 @@ -1222,8 +1225,12 @@ static int alloc_l3_table(struct page_in
  115.29   fail:
  115.30      MEM_LOG("Failure in alloc_l3_table: entry %d", i);
  115.31      while ( i-- > 0 )
  115.32 -        if ( is_guest_l3_slot(i) )
  115.33 -            put_page_from_l3e(pl3e[i], pfn);
  115.34 +    {
  115.35 +        if ( !is_guest_l3_slot(i) )
  115.36 +            continue;
  115.37 +        unadjust_guest_l3e(pl3e[i], d);
  115.38 +        put_page_from_l3e(pl3e[i], pfn);
  115.39 +    }
  115.40  
  115.41      unmap_domain_page(pl3e);
  115.42      return 0;
  115.43 @@ -1242,8 +1249,10 @@ static int alloc_l4_table(struct page_in
  115.44  
  115.45      for ( i = 0; i < L4_PAGETABLE_ENTRIES; i++ )
  115.46      {
  115.47 -        if ( is_guest_l4_slot(d, i) &&
  115.48 -             unlikely(!get_page_from_l4e(pl4e[i], pfn, d)) )
  115.49 +        if ( !is_guest_l4_slot(d, i) )
  115.50 +            continue;
  115.51 +
  115.52 +        if ( unlikely(!get_page_from_l4e(pl4e[i], pfn, d)) )
  115.53              goto fail;
  115.54  
  115.55          adjust_guest_l4e(pl4e[i], d);
  115.56 @@ -1585,7 +1594,7 @@ static int mod_l3_entry(l3_pgentry_t *pl
  115.57      struct vcpu *curr = current;
  115.58      struct domain *d = curr->domain;
  115.59      struct page_info *l3pg = mfn_to_page(pfn);
  115.60 -    int okay, rc = 1;
  115.61 +    int rc = 1;
  115.62  
  115.63      if ( unlikely(!is_guest_l3_slot(pgentry_ptr_to_slot(pl3e))) )
  115.64      {
  115.65 @@ -1642,10 +1651,13 @@ static int mod_l3_entry(l3_pgentry_t *pl
  115.66          return 0;
  115.67      }
  115.68  
  115.69 -    okay = create_pae_xen_mappings(d, pl3e);
  115.70 -    BUG_ON(!okay);
  115.71 -
  115.72 -    pae_flush_pgd(pfn, pgentry_ptr_to_slot(pl3e), nl3e);
  115.73 +    if ( likely(rc) )
  115.74 +    {
  115.75 +        if ( !create_pae_xen_mappings(d, pl3e) )
  115.76 +            BUG();
  115.77 +
  115.78 +        pae_flush_pgd(pfn, pgentry_ptr_to_slot(pl3e), nl3e);
  115.79 +    }
  115.80  
  115.81      page_unlock(l3pg);
  115.82      put_page_from_l3e(ol3e, pfn);
   116.1 --- a/xen/arch/x86/mm/shadow/multi.c	Thu Aug 07 11:47:34 2008 +0900
   116.2 +++ b/xen/arch/x86/mm/shadow/multi.c	Thu Aug 07 11:57:34 2008 +0900
   116.3 @@ -3359,7 +3359,7 @@ static int sh_page_fault(struct vcpu *v,
   116.4              gdprintk(XENLOG_DEBUG, "guest attempted write to read-only memory"
   116.5                       " page. va page=%#lx, mfn=%#lx\n",
   116.6                       va & PAGE_MASK, mfn_x(gmfn));
   116.7 -        goto emulate; /* skip over the instruction */
   116.8 +        goto emulate_readonly; /* skip over the instruction */
   116.9      }
  116.10  
  116.11      /* In HVM guests, we force CR0.WP always to be set, so that the
  116.12 @@ -3405,6 +3405,11 @@ static int sh_page_fault(struct vcpu *v,
  116.13      }
  116.14  
  116.15      /*
  116.16 +     * Write from userspace to ro-mem needs to jump here to avoid getting
  116.17 +     * caught by user-mode page-table check above.
  116.18 +     */
  116.19 + emulate_readonly:
  116.20 +    /*
  116.21       * We don't need to hold the lock for the whole emulation; we will
  116.22       * take it again when we write to the pagetables.
  116.23       */
  116.24 @@ -4640,15 +4645,9 @@ static void *emulate_map_dest(struct vcp
  116.25                                u32 bytes,
  116.26                                struct sh_emulate_ctxt *sh_ctxt)
  116.27  {
  116.28 -    struct segment_register *sreg;
  116.29      unsigned long offset;
  116.30      void *map = NULL;
  116.31  
  116.32 -    /* We don't emulate user-mode writes to page tables */
  116.33 -    sreg = hvm_get_seg_reg(x86_seg_ss, sh_ctxt);
  116.34 -    if ( sreg->attr.fields.dpl == 3 )
  116.35 -        return MAPPING_UNHANDLEABLE;
  116.36 -
  116.37      sh_ctxt->mfn1 = emulate_gva_to_mfn(v, vaddr, sh_ctxt);
  116.38      if ( !mfn_valid(sh_ctxt->mfn1) ) 
  116.39          return ((mfn_x(sh_ctxt->mfn1) == BAD_GVA_TO_GFN) ?
  116.40 @@ -4656,6 +4655,16 @@ static void *emulate_map_dest(struct vcp
  116.41                  (mfn_x(sh_ctxt->mfn1) == READONLY_GFN) ?
  116.42                  MAPPING_SILENT_FAIL : MAPPING_UNHANDLEABLE);
  116.43  
  116.44 +#ifndef NDEBUG
  116.45 +    /* We don't emulate user-mode writes to page tables */
  116.46 +    if ( hvm_get_seg_reg(x86_seg_ss, sh_ctxt)->attr.fields.dpl == 3 )
  116.47 +    {
  116.48 +        gdprintk(XENLOG_DEBUG, "User-mode write to pagetable reached "
  116.49 +                 "emulate_map_dest(). This should never happen!\n");
  116.50 +        return MAPPING_UNHANDLEABLE;
  116.51 +    }
  116.52 +#endif
  116.53 +                
  116.54      /* Unaligned writes mean probably this isn't a pagetable */
  116.55      if ( vaddr & (bytes - 1) )
  116.56          sh_remove_shadows(v, sh_ctxt->mfn1, 0, 0 /* Slow, can fail */ );
   117.1 --- a/xen/arch/x86/msi.c	Thu Aug 07 11:47:34 2008 +0900
   117.2 +++ b/xen/arch/x86/msi.c	Thu Aug 07 11:57:34 2008 +0900
   117.3 @@ -27,8 +27,6 @@
   117.4  #include <public/physdev.h>
   117.5  #include <xen/iommu.h>
   117.6  
   117.7 -extern int msi_irq_enable;
   117.8 -
   117.9  /* bitmap indicate which fixed map is free */
  117.10  DEFINE_SPINLOCK(msix_fixmap_lock);
  117.11  DECLARE_BITMAP(msix_fixmap_pages, MAX_MSIX_PAGES);
  117.12 @@ -763,14 +761,13 @@ retry:
  117.13      {
  117.14          desc = &irq_desc[entry->vector];
  117.15  
  117.16 -	local_irq_save(flags);
  117.17 -	if ( !spin_trylock(&desc->lock) )
  117.18 -	{
  117.19 -	    local_irq_restore(flags);
  117.20 -	    goto retry;
  117.21 -	}
  117.22 +        local_irq_save(flags);
  117.23 +        if ( !spin_trylock(&desc->lock) )
  117.24 +        {
  117.25 +             local_irq_restore(flags);
  117.26 +            goto retry;
  117.27 +        }
  117.28  
  117.29 -        spin_lock_irqsave(&desc->lock, flags);
  117.30          if ( desc->handler == &pci_msi_type )
  117.31          {
  117.32              /* MSI is not shared, so should be released already */
   118.1 --- a/xen/arch/x86/numa.c	Thu Aug 07 11:47:34 2008 +0900
   118.2 +++ b/xen/arch/x86/numa.c	Thu Aug 07 11:57:34 2008 +0900
   118.3 @@ -14,6 +14,7 @@
   118.4  #include <xen/time.h>
   118.5  #include <xen/smp.h>
   118.6  #include <asm/acpi.h>
   118.7 +#include <xen/sched.h>
   118.8  
   118.9  static int numa_setup(char *s);
  118.10  custom_param("numa", numa_setup);
  118.11 @@ -281,6 +282,9 @@ static void dump_numa(unsigned char key)
  118.12  {
  118.13  	s_time_t now = NOW();
  118.14  	int i;
  118.15 +	struct domain *d;
  118.16 +	struct page_info *page;
  118.17 +	unsigned int page_num_node[MAX_NUMNODES];
  118.18  
  118.19  	printk("'%c' pressed -> dumping numa info (now-0x%X:%08X)\n", key,
  118.20  		  (u32)(now>>32), (u32)now);
  118.21 @@ -297,6 +301,28 @@ static void dump_numa(unsigned char key)
  118.22  	}
  118.23  	for_each_online_cpu(i)
  118.24  		printk("CPU%d -> NODE%d\n", i, cpu_to_node[i]);
  118.25 +
  118.26 +	rcu_read_lock(&domlist_read_lock);
  118.27 +
  118.28 +	printk("Memory location of each domain:\n");
  118.29 +	for_each_domain(d)
  118.30 +	{
  118.31 +		printk("Domain %u (total: %u):\n", d->domain_id, d->tot_pages);
  118.32 +
  118.33 +		for_each_online_node(i)
  118.34 +			page_num_node[i] = 0;
  118.35 +
  118.36 +		list_for_each_entry(page, &d->page_list, list)
  118.37 +		{
  118.38 +			i = phys_to_nid(page_to_mfn(page) << PAGE_SHIFT);
  118.39 +			page_num_node[i]++;
  118.40 +		}
  118.41 +
  118.42 +		for_each_online_node(i)
  118.43 +			printk("    Node %u: %u\n", i, page_num_node[i]);
  118.44 +	}
  118.45 +
  118.46 +	rcu_read_unlock(&domlist_read_lock);
  118.47  }
  118.48  
  118.49  static __init int register_numa_trigger(void)
   119.1 --- a/xen/arch/x86/physdev.c	Thu Aug 07 11:47:34 2008 +0900
   119.2 +++ b/xen/arch/x86/physdev.c	Thu Aug 07 11:57:34 2008 +0900
   119.3 @@ -184,15 +184,14 @@ static int unmap_domain_pirq(struct doma
   119.4      return ret;
   119.5  }
   119.6  
   119.7 -extern int msi_irq_enable;
   119.8  static int physdev_map_pirq(struct physdev_map_pirq *map)
   119.9  {
  119.10      struct domain *d;
  119.11      int vector, pirq, ret = 0;
  119.12      unsigned long flags;
  119.13  
  119.14 -    /* if msi_irq_enable is not enabled,map always success */
  119.15 -    if ( !msi_irq_enable )
  119.16 +    /* if msi_enable is not enabled, map always succeeds */
  119.17 +    if ( !msi_enable )
  119.18          return 0;
  119.19  
  119.20      if ( !IS_PRIV(current->domain) )
  119.21 @@ -304,7 +303,7 @@ static int physdev_unmap_pirq(struct phy
  119.22      unsigned long flags;
  119.23      int ret;
  119.24  
  119.25 -    if ( !msi_irq_enable )
  119.26 +    if ( !msi_enable )
  119.27          return 0;
  119.28  
  119.29      if ( !IS_PRIV(current->domain) )
  119.30 @@ -455,7 +454,7 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
  119.31  
  119.32          ret = 0;
  119.33  
  119.34 -        if ( msi_irq_enable )
  119.35 +        if ( msi_enable )
  119.36          {
  119.37              spin_lock_irqsave(&dom0->arch.irq_lock, flags);
  119.38              if ( irq != AUTO_ASSIGN )
   120.1 --- a/xen/arch/x86/platform_hypercall.c	Thu Aug 07 11:47:34 2008 +0900
   120.2 +++ b/xen/arch/x86/platform_hypercall.c	Thu Aug 07 11:57:34 2008 +0900
   120.3 @@ -355,6 +355,11 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
   120.4              struct processor_pminfo *pmpt;
   120.5              struct processor_performance *pxpt;
   120.6  
   120.7 +            if ( !(xen_processor_pmbits & XEN_PROCESSOR_PM_PX) )
   120.8 +            {
   120.9 +                ret = -ENOSYS;
  120.10 +                break;
  120.11 +            }
  120.12              if ( cpuid < 0 )
  120.13              {
  120.14                  ret = -EINVAL;
  120.15 @@ -373,6 +378,7 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
  120.16                  memcpy ((void *)&pxpt->status_register,
  120.17                      (void *)&xenpxpt->status_register,
  120.18                      sizeof(struct xen_pct_register));
  120.19 +                pxpt->init |= XEN_PX_PCT;
  120.20              }
  120.21              if ( xenpxpt->flags & XEN_PX_PSS ) 
  120.22              {
  120.23 @@ -390,6 +396,7 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
  120.24                      break;
  120.25                  }
  120.26                  pxpt->state_count = xenpxpt->state_count;
  120.27 +                pxpt->init |= XEN_PX_PSS;
  120.28              }
  120.29              if ( xenpxpt->flags & XEN_PX_PSD )
  120.30              {
  120.31 @@ -397,14 +404,18 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
  120.32                  memcpy ((void *)&pxpt->domain_info,
  120.33                      (void *)&xenpxpt->domain_info,
  120.34                      sizeof(struct xen_psd_package));
  120.35 +                pxpt->init |= XEN_PX_PSD;
  120.36              }
  120.37              if ( xenpxpt->flags & XEN_PX_PPC )
  120.38 +            {
  120.39                  pxpt->ppc = xenpxpt->ppc;
  120.40 +                pxpt->init |= XEN_PX_PPC;
  120.41 +            }
  120.42  
  120.43 -            if ( xenpxpt->flags == ( XEN_PX_PCT | XEN_PX_PSS | 
  120.44 -                XEN_PX_PSD | XEN_PX_PPC ) )
  120.45 +            if ( pxpt->init == ( XEN_PX_PCT | XEN_PX_PSS |
  120.46 +                                 XEN_PX_PSD | XEN_PX_PPC ) )
  120.47              {
  120.48 -                pxpt->init =1;
  120.49 +                pxpt->init |= XEN_PX_INIT;
  120.50                  cpu_count++;
  120.51              }
  120.52              if ( cpu_count == num_online_cpus() )
  120.53 @@ -418,10 +429,20 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
  120.54          }
  120.55   
  120.56          case XEN_PM_CX:
  120.57 +            if ( !(xen_processor_pmbits & XEN_PROCESSOR_PM_CX) )
  120.58 +            {
  120.59 +                ret = -ENOSYS;
  120.60 +                break;
  120.61 +            }
  120.62              ret = set_cx_pminfo(op->u.set_pminfo.id, &op->u.set_pminfo.power);
  120.63              break;
  120.64  
  120.65          case XEN_PM_TX:
  120.66 +            if ( !(xen_processor_pmbits & XEN_PROCESSOR_PM_TX) )
  120.67 +            {
  120.68 +                ret = -ENOSYS;
  120.69 +                break;
  120.70 +            }
  120.71              ret = -EINVAL;
  120.72              break;
  120.73  
   121.1 --- a/xen/arch/x86/setup.c	Thu Aug 07 11:47:34 2008 +0900
   121.2 +++ b/xen/arch/x86/setup.c	Thu Aug 07 11:57:34 2008 +0900
   121.3 @@ -997,7 +997,6 @@ void __init __start_xen(unsigned long mb
   121.4      if ( (cmdline != NULL) || (kextra != NULL) )
   121.5      {
   121.6          static char dom0_cmdline[MAX_GUEST_CMDLINE];
   121.7 -        char xen_pm_param[32];
   121.8  
   121.9          cmdline = cmdline_cook(cmdline);
  121.10          safe_strcpy(dom0_cmdline, cmdline);
  121.11 @@ -1022,14 +1021,6 @@ void __init __start_xen(unsigned long mb
  121.12              safe_strcat(dom0_cmdline, " acpi=");
  121.13              safe_strcat(dom0_cmdline, acpi_param);
  121.14          }
  121.15 -        if ( xen_cpuidle )
  121.16 -            xen_processor_pmbits |= XEN_PROCESSOR_PM_CX;
  121.17 -
  121.18 -        snprintf(xen_pm_param, sizeof(xen_pm_param), 
  121.19 -            " xen_processor_pmbits=%d", xen_processor_pmbits);
  121.20 -
  121.21 -        if ( !strstr(dom0_cmdline, "xen_processor_pmbits=") )
  121.22 -            safe_strcat(dom0_cmdline, xen_pm_param);
  121.23  
  121.24          cmdline = dom0_cmdline;
  121.25      }
  121.26 @@ -1041,6 +1032,9 @@ void __init __start_xen(unsigned long mb
  121.27          _initrd_len   = mod[initrdidx].mod_end - mod[initrdidx].mod_start;
  121.28      }
  121.29  
  121.30 +    if ( xen_cpuidle )
  121.31 +        xen_processor_pmbits |= XEN_PROCESSOR_PM_CX;
  121.32 +
  121.33      /*
  121.34       * We're going to setup domain0 using the module(s) that we stashed safely
  121.35       * above our heap. The second module, if present, is an initrd ramdisk.
   122.1 --- a/xen/arch/x86/shutdown.c	Thu Aug 07 11:47:34 2008 +0900
   122.2 +++ b/xen/arch/x86/shutdown.c	Thu Aug 07 11:57:34 2008 +0900
   122.3 @@ -291,7 +291,12 @@ static int __init reboot_init(void)
   122.4  
   122.5  #endif
   122.6  
   122.7 -void machine_restart(void)
   122.8 +static void __machine_restart(void *pdelay)
   122.9 +{
  122.10 +    machine_restart(*(unsigned int *)pdelay);
  122.11 +}
  122.12 +
  122.13 +void machine_restart(unsigned int delay_millisecs)
  122.14  {
  122.15      int i;
  122.16  
  122.17 @@ -304,14 +309,16 @@ void machine_restart(void)
  122.18      if ( get_apic_id() != boot_cpu_physical_apicid )
  122.19      {
  122.20          /* Send IPI to the boot CPU (logical cpu 0). */
  122.21 -        on_selected_cpus(cpumask_of_cpu(0), (void *)machine_restart,
  122.22 -                         NULL, 1, 0);
  122.23 +        on_selected_cpus(cpumask_of_cpu(0), __machine_restart,
  122.24 +                         &delay_millisecs, 1, 0);
  122.25          for ( ; ; )
  122.26              halt();
  122.27      }
  122.28  
  122.29      smp_send_stop();
  122.30  
  122.31 +    mdelay(delay_millisecs);
  122.32 +
  122.33      if ( tboot_in_measured_env() )
  122.34          tboot_shutdown(TB_SHUTDOWN_REBOOT);
  122.35  
   123.1 --- a/xen/arch/x86/time.c	Thu Aug 07 11:47:34 2008 +0900
   123.2 +++ b/xen/arch/x86/time.c	Thu Aug 07 11:57:34 2008 +0900
   123.3 @@ -35,8 +35,6 @@
   123.4  static char opt_clocksource[10];
   123.5  string_param("clocksource", opt_clocksource);
   123.6  
   123.7 -#define EPOCH MILLISECS(1000)
   123.8 -
   123.9  unsigned long cpu_khz;  /* CPU clock frequency in kHz. */
  123.10  DEFINE_SPINLOCK(rtc_lock);
  123.11  unsigned long pit0_ticks;
  123.12 @@ -55,7 +53,6 @@ struct cpu_time {
  123.13      s_time_t stime_master_stamp;
  123.14      struct time_scale tsc_scale;
  123.15      u64 cstate_plt_count_stamp;
  123.16 -    struct timer calibration_timer;
  123.17  };
  123.18  
  123.19  struct platform_timesource {
  123.20 @@ -67,6 +64,10 @@ struct platform_timesource {
  123.21  
  123.22  static DEFINE_PER_CPU(struct cpu_time, cpu_time);
  123.23  
  123.24 +/* Calibrate all CPUs to platform timer every EPOCH. */
  123.25 +#define EPOCH MILLISECS(1000)
  123.26 +static struct timer calibration_timer;
  123.27 +
  123.28  /* TSC is invariant on C state entry? */
  123.29  static bool_t tsc_invariant;
  123.30  
  123.31 @@ -481,35 +482,6 @@ static int init_pmtimer(struct platform_
  123.32  }
  123.33  
  123.34  /************************************************************
  123.35 - * PLATFORM TIMER 5: TSC
  123.36 - */
  123.37 -
  123.38 -static const char plt_tsc_name[] = "TSC";
  123.39 -#define platform_timer_is_tsc() (plt_src.name == plt_tsc_name)
  123.40 -
  123.41 -static int init_tsctimer(struct platform_timesource *pts)
  123.42 -{
  123.43 -    if ( !tsc_invariant )
  123.44 -        return 0;
  123.45 -
  123.46 -    pts->name = (char *)plt_tsc_name;
  123.47 -    return 1;
  123.48 -}
  123.49 -
  123.50 -static void make_tsctimer_record(void)
  123.51 -{
  123.52 -    struct cpu_time *t = &this_cpu(cpu_time);
  123.53 -    s_time_t now;
  123.54 -    u64 tsc;
  123.55 -
  123.56 -    rdtscll(tsc);
  123.57 -    now = scale_delta(tsc, &t->tsc_scale);
  123.58 -
  123.59 -    t->local_tsc_stamp = tsc;
  123.60 -    t->stime_local_stamp = t->stime_master_stamp = now;
  123.61 -}
  123.62 -
  123.63 -/************************************************************
  123.64   * GENERIC PLATFORM TIMER INFRASTRUCTURE
  123.65   */
  123.66  
  123.67 @@ -530,11 +502,11 @@ static void plt_overflow(void *unused)
  123.68  {
  123.69      u64 count;
  123.70  
  123.71 -    spin_lock(&platform_timer_lock);
  123.72 +    spin_lock_irq(&platform_timer_lock);
  123.73      count = plt_src.read_counter();
  123.74      plt_stamp64 += (count - plt_stamp) & plt_mask;
  123.75      plt_stamp = count;
  123.76 -    spin_unlock(&platform_timer_lock);
  123.77 +    spin_unlock_irq(&platform_timer_lock);
  123.78  
  123.79      set_timer(&plt_overflow_timer, NOW() + plt_overflow_period);
  123.80  }
  123.81 @@ -551,6 +523,8 @@ static s_time_t read_platform_stime(void
  123.82      u64 count;
  123.83      s_time_t stime;
  123.84  
  123.85 +    ASSERT(!local_irq_is_enabled());
  123.86 +
  123.87      spin_lock(&platform_timer_lock);
  123.88      count = plt_stamp64 + ((plt_src.read_counter() - plt_stamp) & plt_mask);
  123.89      stime = __read_platform_stime(count);
  123.90 @@ -564,22 +538,16 @@ static void platform_time_calibration(vo
  123.91      u64 count;
  123.92      s_time_t stamp;
  123.93  
  123.94 -    spin_lock(&platform_timer_lock);
  123.95 +    spin_lock_irq(&platform_timer_lock);
  123.96      count = plt_stamp64 + ((plt_src.read_counter() - plt_stamp) & plt_mask);
  123.97      stamp = __read_platform_stime(count);
  123.98      stime_platform_stamp = stamp;
  123.99      platform_timer_stamp = count;
 123.100 -    spin_unlock(&platform_timer_lock);
 123.101 +    spin_unlock_irq(&platform_timer_lock);
 123.102  }
 123.103  
 123.104  static void resume_platform_timer(void)
 123.105  {
 123.106 -    if ( platform_timer_is_tsc() )
 123.107 -    {
 123.108 -        /* TODO: Save/restore TSC values. */
 123.109 -        return;
 123.110 -    }
 123.111 -
 123.112      /* No change in platform_stime across suspend/resume. */
 123.113      platform_timer_stamp = plt_stamp64;
 123.114      plt_stamp = plt_src.read_counter();
 123.115 @@ -600,8 +568,6 @@ static void init_platform_timer(void)
 123.116              rc = init_cyclone(pts);
 123.117          else if ( !strcmp(opt_clocksource, "acpi") )
 123.118              rc = init_pmtimer(pts);
 123.119 -        else if ( !strcmp(opt_clocksource, "tsc") )
 123.120 -            rc = init_tsctimer(pts);
 123.121  
 123.122          if ( rc <= 0 )
 123.123              printk("WARNING: %s clocksource '%s'.\n",
 123.124 @@ -615,12 +581,6 @@ static void init_platform_timer(void)
 123.125           !init_pmtimer(pts) )
 123.126          init_pit(pts);
 123.127  
 123.128 -    if ( platform_timer_is_tsc() )
 123.129 -    {
 123.130 -        printk("Platform timer is TSC\n");
 123.131 -        return;
 123.132 -    }
 123.133 -
 123.134      plt_mask = (u64)~0ull >> (64 - pts->counter_bits);
 123.135  
 123.136      set_time_scale(&plt_scale, pts->frequency);
 123.137 @@ -823,10 +783,6 @@ int cpu_frequency_change(u64 freq)
 123.138      struct cpu_time *t = &this_cpu(cpu_time);
 123.139      u64 curr_tsc;
 123.140  
 123.141 -    /* Nothing to do if TSC is platform timer. Assume it is constant-rate. */
 123.142 -    if ( platform_timer_is_tsc() )
 123.143 -        return 0;
 123.144 -
 123.145      /* Sanity check: CPU frequency allegedly dropping below 1MHz? */
 123.146      if ( freq < 1000000u )
 123.147      {
 123.148 @@ -847,9 +803,11 @@ int cpu_frequency_change(u64 freq)
 123.149      local_irq_enable();
 123.150  
 123.151      /* A full epoch should pass before we check for deviation. */
 123.152 -    set_timer(&t->calibration_timer, NOW() + EPOCH);
 123.153      if ( smp_processor_id() == 0 )
 123.154 +    {
 123.155 +        set_timer(&calibration_timer, NOW() + EPOCH);
 123.156          platform_time_calibration();
 123.157 +    }
 123.158  
 123.159      return 0;
 123.160  }
 123.161 @@ -875,9 +833,20 @@ void do_settime(unsigned long secs, unsi
 123.162      rcu_read_unlock(&domlist_read_lock);
 123.163  }
 123.164  
 123.165 +/* Per-CPU communication between rendezvous IRQ and softirq handler. */
 123.166 +struct cpu_calibration {
 123.167 +    u64 local_tsc_stamp;
 123.168 +    s_time_t stime_local_stamp;
 123.169 +    s_time_t stime_master_stamp;
 123.170 +    struct timer softirq_callback;
 123.171 +};
 123.172 +static DEFINE_PER_CPU(struct cpu_calibration, cpu_calibration);
 123.173 +
 123.174 +/* Softirq handler for per-CPU time calibration. */
 123.175  static void local_time_calibration(void *unused)
 123.176  {
 123.177      struct cpu_time *t = &this_cpu(cpu_time);
 123.178 +    struct cpu_calibration *c = &this_cpu(cpu_calibration);
 123.179  
 123.180      /*
 123.181       * System timestamps, extrapolated from local and master oscillators,
 123.182 @@ -908,26 +877,15 @@ static void local_time_calibration(void 
 123.183      /* The overall calibration scale multiplier. */
 123.184      u32 calibration_mul_frac;
 123.185  
 123.186 -    if ( platform_timer_is_tsc() )
 123.187 -    {
 123.188 -        make_tsctimer_record(); 
 123.189 -        update_vcpu_system_time(current);
 123.190 -        set_timer(&t->calibration_timer, NOW() + MILLISECS(10*1000));
 123.191 -        return;
 123.192 -    }
 123.193 -
 123.194      prev_tsc          = t->local_tsc_stamp;
 123.195      prev_local_stime  = t->stime_local_stamp;
 123.196      prev_master_stime = t->stime_master_stamp;
 123.197  
 123.198 -    /*
 123.199 -     * Disable IRQs to get 'instantaneous' current timestamps. We read platform
 123.200 -     * time first, as we may be delayed when acquiring platform_timer_lock.
 123.201 -     */
 123.202 +    /* Disabling IRQs ensures we atomically read cpu_calibration struct. */
 123.203      local_irq_disable();
 123.204 -    curr_master_stime = read_platform_stime();
 123.205 -    curr_local_stime  = get_s_time();
 123.206 -    rdtscll(curr_tsc);
 123.207 +    curr_tsc          = c->local_tsc_stamp;
 123.208 +    curr_local_stime  = c->stime_local_stamp;
 123.209 +    curr_master_stime = c->stime_master_stamp;
 123.210      local_irq_enable();
 123.211  
 123.212  #if 0
 123.213 @@ -1021,10 +979,62 @@ static void local_time_calibration(void 
 123.214      update_vcpu_system_time(current);
 123.215  
 123.216   out:
 123.217 -    set_timer(&t->calibration_timer, NOW() + EPOCH);
 123.218 +    if ( smp_processor_id() == 0 )
 123.219 +    {
 123.220 +        set_timer(&calibration_timer, NOW() + EPOCH);
 123.221 +        platform_time_calibration();
 123.222 +    }
 123.223 +}
 123.224 +
 123.225 +/*
 123.226 + * Rendezvous for all CPUs in IRQ context.
 123.227 + * Master CPU snapshots the platform timer.
 123.228 + * All CPUS snapshot their local TSC and extrapolation of system time.
 123.229 + */
 123.230 +struct calibration_rendezvous {
 123.231 +    atomic_t nr_cpus;
 123.232 +    s_time_t master_stime;
 123.233 +};
 123.234 +
 123.235 +static void time_calibration_rendezvous(void *_r)
 123.236 +{
 123.237 +    unsigned int total_cpus = num_online_cpus();
 123.238 +    struct cpu_calibration *c = &this_cpu(cpu_calibration);
 123.239 +    struct calibration_rendezvous *r = _r;
 123.240 +
 123.241 +    local_irq_disable();
 123.242  
 123.243      if ( smp_processor_id() == 0 )
 123.244 -        platform_time_calibration();
 123.245 +    {
 123.246 +        while ( atomic_read(&r->nr_cpus) != (total_cpus - 1) )
 123.247 +            cpu_relax();
 123.248 +        r->master_stime = read_platform_stime();
 123.249 +        atomic_inc(&r->nr_cpus);
 123.250 +    }
 123.251 +    else
 123.252 +    {
 123.253 +        atomic_inc(&r->nr_cpus);
 123.254 +        while ( atomic_read(&r->nr_cpus) != total_cpus )
 123.255 +            cpu_relax();
 123.256 +    }
 123.257 +
 123.258 +    rdtscll(c->local_tsc_stamp);
 123.259 +    c->stime_local_stamp = get_s_time();
 123.260 +    c->stime_master_stamp = r->master_stime;
 123.261 +
 123.262 +    local_irq_enable();
 123.263 +
 123.264 +    /* Callback in softirq context as soon as possible. */
 123.265 +    set_timer(&c->softirq_callback, c->stime_local_stamp);
 123.266 +}
 123.267 +
 123.268 +static void time_calibration(void *unused)
 123.269 +{
 123.270 +    struct calibration_rendezvous r = {
 123.271 +        .nr_cpus = ATOMIC_INIT(0)
 123.272 +    };
 123.273 +
 123.274 +    on_each_cpu(time_calibration_rendezvous, &r, 0, 1);
 123.275  }
 123.276  
 123.277  void init_percpu_time(void)
 123.278 @@ -1033,12 +1043,6 @@ void init_percpu_time(void)
 123.279      unsigned long flags;
 123.280      s_time_t now;
 123.281  
 123.282 -    if ( platform_timer_is_tsc() )
 123.283 -    {
 123.284 -        make_tsctimer_record();
 123.285 -        goto out;
 123.286 -    }
 123.287 -
 123.288      local_irq_save(flags);
 123.289      rdtscll(t->local_tsc_stamp);
 123.290      now = !plt_src.read_counter ? 0 : read_platform_stime();
 123.291 @@ -1047,10 +1051,14 @@ void init_percpu_time(void)
 123.292      t->stime_master_stamp = now;
 123.293      t->stime_local_stamp  = now;
 123.294  
 123.295 - out:
 123.296 -    init_timer(&t->calibration_timer, local_time_calibration,
 123.297 -               NULL, smp_processor_id());
 123.298 -    set_timer(&t->calibration_timer, NOW() + EPOCH);
 123.299 +    init_timer(&this_cpu(cpu_calibration).softirq_callback,
 123.300 +               local_time_calibration, NULL, smp_processor_id());
 123.301 +
 123.302 +    if ( smp_processor_id() == 0 )
 123.303 +    {
 123.304 +        init_timer(&calibration_timer, time_calibration, NULL, 0);
 123.305 +        set_timer(&calibration_timer, NOW() + EPOCH);
 123.306 +    }
 123.307  }
 123.308  
 123.309  /* Late init function (after all CPUs are booted). */
 123.310 @@ -1134,7 +1142,10 @@ void pit_broadcast_enter(void)
 123.311  
 123.312  void pit_broadcast_exit(void)
 123.313  {
 123.314 -    cpu_clear(smp_processor_id(), pit_broadcast_mask);
 123.315 +    int cpu = smp_processor_id();
 123.316 +
 123.317 +    if ( cpu_test_and_clear(cpu, pit_broadcast_mask) )
 123.318 +        reprogram_timer(per_cpu(timer_deadline, cpu));
 123.319  }
 123.320  
 123.321  int pit_broadcast_is_available(void)
 123.322 @@ -1163,10 +1174,11 @@ int time_suspend(void)
 123.323      {
 123.324          cmos_utc_offset = -get_cmos_time();
 123.325          cmos_utc_offset += (wc_sec + (wc_nsec + NOW()) / 1000000000ULL);
 123.326 +        kill_timer(&calibration_timer);
 123.327      }
 123.328  
 123.329      /* Better to cancel calibration timer for accuracy. */
 123.330 -    kill_timer(&this_cpu(cpu_time).calibration_timer);
 123.331 +    kill_timer(&this_cpu(cpu_calibration).softirq_callback);
 123.332  
 123.333      return 0;
 123.334  }
   124.1 --- a/xen/arch/x86/x86_64/physdev.c	Thu Aug 07 11:47:34 2008 +0900
   124.2 +++ b/xen/arch/x86/x86_64/physdev.c	Thu Aug 07 11:57:34 2008 +0900
   124.3 @@ -30,6 +30,15 @@
   124.4  #define physdev_irq_status_query   compat_physdev_irq_status_query
   124.5  #define physdev_irq_status_query_t physdev_irq_status_query_compat_t
   124.6  
   124.7 +#define physdev_map_pirq           compat_physdev_map_pirq
   124.8 +#define physdev_map_pirq_t         physdev_map_pirq_compat_t
   124.9 +
  124.10 +#define physdev_unmap_pirq         compat_physdev_unmap_pirq
  124.11 +#define physdev_unmap_pirq_t       physdev_unmap_pirq_compat_t
  124.12 +
  124.13 +#define physdev_manage_pci         compat_physdev_manage_pci
  124.14 +#define physdev_manage_pci_t       physdev_manage_pci_compat_t
  124.15 +
  124.16  #define COMPAT
  124.17  #undef guest_handle_okay
  124.18  #define guest_handle_okay          compat_handle_okay
   125.1 --- a/xen/arch/x86/x86_emulate/x86_emulate.c	Thu Aug 07 11:47:34 2008 +0900
   125.2 +++ b/xen/arch/x86/x86_emulate/x86_emulate.c	Thu Aug 07 11:57:34 2008 +0900
   125.3 @@ -1606,6 +1606,7 @@ x86_emulate(
   125.4          dst.val = _regs.eax;
   125.5      case 0x38 ... 0x3b: cmp: /* cmp */
   125.6          emulate_2op_SrcV("cmp", src, dst, _regs.eflags);
   125.7 +        dst.type = OP_NONE;
   125.8          break;
   125.9  
  125.10      case 0x62: /* bound */ {
  125.11 @@ -1707,6 +1708,7 @@ x86_emulate(
  125.12          dst.val = _regs.eax;
  125.13      case 0x84 ... 0x85: test: /* test */
  125.14          emulate_2op_SrcV("test", src, dst, _regs.eflags);
  125.15 +        dst.type = OP_NONE;
  125.16          break;
  125.17  
  125.18      case 0x86 ... 0x87: xchg: /* xchg */
   126.1 --- a/xen/common/compat/grant_table.c	Thu Aug 07 11:47:34 2008 +0900
   126.2 +++ b/xen/common/compat/grant_table.c	Thu Aug 07 11:57:34 2008 +0900
   126.3 @@ -138,7 +138,6 @@ int compat_grant_table_op(unsigned int c
   126.4                          for ( i = 0; i < (_s_)->nr_frames; ++i ) \
   126.5                          { \
   126.6                              unsigned int frame = (_s_)->frame_list.p[i]; \
   126.7 -                            BUG_ON(frame != (_s_)->frame_list.p[i]); \
   126.8                              (void)__copy_to_compat_offset((_d_)->frame_list, i, &frame, 1); \
   126.9                          } \
  126.10                      } \
   127.1 --- a/xen/common/domain.c	Thu Aug 07 11:47:34 2008 +0900
   127.2 +++ b/xen/common/domain.c	Thu Aug 07 11:57:34 2008 +0900
   127.3 @@ -50,7 +50,7 @@ static void __init setup_cpufreq_option(
   127.4      else if ( !strcmp(str, "xen") )
   127.5      {
   127.6          xen_processor_pmbits |= XEN_PROCESSOR_PM_PX;
   127.7 -        cpufreq_controller = FREQCTL_none;
   127.8 +        cpufreq_controller = FREQCTL_xen;
   127.9      }
  127.10  }
  127.11  custom_param("cpufreq", setup_cpufreq_option);
  127.12 @@ -137,6 +137,8 @@ struct vcpu *alloc_vcpu(
  127.13      v->runstate.state = is_idle_vcpu(v) ? RUNSTATE_running : RUNSTATE_offline;
  127.14      v->runstate.state_entry_time = NOW();
  127.15  
  127.16 +    spin_lock_init(&v->virq_lock);
  127.17 +
  127.18      if ( !is_idle_domain(d) )
  127.19      {
  127.20          set_bit(_VPF_down, &v->pause_flags);
   128.1 --- a/xen/common/event_channel.c	Thu Aug 07 11:47:34 2008 +0900
   128.2 +++ b/xen/common/event_channel.c	Thu Aug 07 11:57:34 2008 +0900
   128.3 @@ -386,14 +386,18 @@ static long __evtchn_close(struct domain
   128.4          break;
   128.5  
   128.6      case ECS_PIRQ:
   128.7 -        if ( (rc = pirq_guest_unbind(d1, chn1->u.pirq)) == 0 )
   128.8 -            d1->pirq_to_evtchn[chn1->u.pirq] = 0;
   128.9 +        pirq_guest_unbind(d1, chn1->u.pirq);
  128.10 +        d1->pirq_to_evtchn[chn1->u.pirq] = 0;
  128.11          break;
  128.12  
  128.13      case ECS_VIRQ:
  128.14          for_each_vcpu ( d1, v )
  128.15 -            if ( v->virq_to_evtchn[chn1->u.virq] == port1 )
  128.16 -                v->virq_to_evtchn[chn1->u.virq] = 0;
  128.17 +        {
  128.18 +            if ( v->virq_to_evtchn[chn1->u.virq] != port1 )
  128.19 +                continue;
  128.20 +            v->virq_to_evtchn[chn1->u.virq] = 0;
  128.21 +            spin_barrier(&v->virq_lock);
  128.22 +        }
  128.23          break;
  128.24  
  128.25      case ECS_IPI:
  128.26 @@ -447,6 +451,9 @@ static long __evtchn_close(struct domain
  128.27          BUG();
  128.28      }
  128.29  
  128.30 +    /* Clear pending event to avoid unexpected behavior on re-bind. */
  128.31 +    clear_bit(port1, &shared_info(d1, evtchn_pending));
  128.32 +
  128.33      /* Reset binding to vcpu0 when the channel is freed. */
  128.34      chn1->state          = ECS_FREE;
  128.35      chn1->notify_vcpu_id = 0;
  128.36 @@ -573,37 +580,33 @@ static int evtchn_set_pending(struct vcp
  128.37      return 0;
  128.38  }
  128.39  
  128.40 +int guest_enabled_event(struct vcpu *v, int virq)
  128.41 +{
  128.42 +    return ((v != NULL) && (v->virq_to_evtchn[virq] != 0));
  128.43 +}
  128.44  
  128.45  void send_guest_vcpu_virq(struct vcpu *v, int virq)
  128.46  {
  128.47 +    unsigned long flags;
  128.48      int port;
  128.49  
  128.50      ASSERT(!virq_is_global(virq));
  128.51  
  128.52 +    spin_lock_irqsave(&v->virq_lock, flags);
  128.53 +
  128.54      port = v->virq_to_evtchn[virq];
  128.55      if ( unlikely(port == 0) )
  128.56 -        return;
  128.57 +        goto out;
  128.58  
  128.59      evtchn_set_pending(v, port);
  128.60 -}
  128.61  
  128.62 -int guest_enabled_event(struct vcpu *v, int virq)
  128.63 -{
  128.64 -    int port;
  128.65 -
  128.66 -    if ( unlikely(v == NULL) )
  128.67 -        return 0;
  128.68 -
  128.69 -    port = v->virq_to_evtchn[virq];
  128.70 -    if ( port == 0 )
  128.71 -        return 0;
  128.72 -
  128.73 -    /* virq is in use */
  128.74 -    return 1;
  128.75 + out:
  128.76 +    spin_unlock_irqrestore(&v->virq_lock, flags);
  128.77  }
  128.78  
  128.79  void send_guest_global_virq(struct domain *d, int virq)
  128.80  {
  128.81 +    unsigned long flags;
  128.82      int port;
  128.83      struct vcpu *v;
  128.84      struct evtchn *chn;
  128.85 @@ -617,20 +620,28 @@ void send_guest_global_virq(struct domai
  128.86      if ( unlikely(v == NULL) )
  128.87          return;
  128.88  
  128.89 +    spin_lock_irqsave(&v->virq_lock, flags);
  128.90 +
  128.91      port = v->virq_to_evtchn[virq];
  128.92      if ( unlikely(port == 0) )
  128.93 -        return;
  128.94 +        goto out;
  128.95  
  128.96      chn = evtchn_from_port(d, port);
  128.97      evtchn_set_pending(d->vcpu[chn->notify_vcpu_id], port);
  128.98 +
  128.99 + out:
 128.100 +    spin_unlock_irqrestore(&v->virq_lock, flags);
 128.101  }
 128.102  
 128.103 -
 128.104  int send_guest_pirq(struct domain *d, int pirq)
 128.105  {
 128.106      int port = d->pirq_to_evtchn[pirq];
 128.107      struct evtchn *chn;
 128.108  
 128.109 +    /*
 128.110 +     * It should not be possible to race with __evtchn_close():
 128.111 +     * The caller of this function must synchronise with pirq_guest_unbind().
 128.112 +     */
 128.113      ASSERT(port != 0);
 128.114  
 128.115      chn = evtchn_from_port(d, port);
   129.1 --- a/xen/common/keyhandler.c	Thu Aug 07 11:47:34 2008 +0900
   129.2 +++ b/xen/common/keyhandler.c	Thu Aug 07 11:57:34 2008 +0900
   129.3 @@ -143,7 +143,7 @@ static void dump_dom0_registers(unsigned
   129.4  static void halt_machine(unsigned char key, struct cpu_user_regs *regs)
   129.5  {
   129.6      printk("'%c' pressed -> rebooting machine\n", key);
   129.7 -    machine_restart();
   129.8 +    machine_restart(0);
   129.9  }
  129.10  
  129.11  static void cpuset_print(char *set, int size, cpumask_t mask)
  129.12 @@ -236,6 +236,7 @@ static void dump_domains(unsigned char k
  129.13  
  129.14  static cpumask_t read_clocks_cpumask = CPU_MASK_NONE;
  129.15  static s_time_t read_clocks_time[NR_CPUS];
  129.16 +static u64 read_cycles_time[NR_CPUS];
  129.17  
  129.18  static void read_clocks_slave(void *unused)
  129.19  {
  129.20 @@ -244,14 +245,20 @@ static void read_clocks_slave(void *unus
  129.21      while ( !cpu_isset(cpu, read_clocks_cpumask) )
  129.22          cpu_relax();
  129.23      read_clocks_time[cpu] = NOW();
  129.24 +    read_cycles_time[cpu] = get_cycles();
  129.25      cpu_clear(cpu, read_clocks_cpumask);
  129.26      local_irq_enable();
  129.27  }
  129.28  
  129.29  static void read_clocks(unsigned char key)
  129.30  {
  129.31 -    unsigned int cpu = smp_processor_id(), min_cpu, max_cpu;
  129.32 -    u64 min, max, dif, difus;
  129.33 +    unsigned int cpu = smp_processor_id(), min_stime_cpu, max_stime_cpu;
  129.34 +    unsigned int min_cycles_cpu, max_cycles_cpu;
  129.35 +    u64 min_stime, max_stime, dif_stime;
  129.36 +    u64 min_cycles, max_cycles, dif_cycles;
  129.37 +    static u64 sumdif_stime = 0, maxdif_stime = 0;
  129.38 +    static u64 sumdif_cycles = 0, maxdif_cycles = 0;
  129.39 +    static u32 count = 0;
  129.40      static DEFINE_SPINLOCK(lock);
  129.41  
  129.42      spin_lock(&lock);
  129.43 @@ -261,31 +268,48 @@ static void read_clocks(unsigned char ke
  129.44      local_irq_disable();
  129.45      read_clocks_cpumask = cpu_online_map;
  129.46      read_clocks_time[cpu] = NOW();
  129.47 +    read_cycles_time[cpu] = get_cycles();
  129.48      cpu_clear(cpu, read_clocks_cpumask);
  129.49      local_irq_enable();
  129.50  
  129.51      while ( !cpus_empty(read_clocks_cpumask) )
  129.52          cpu_relax();
  129.53  
  129.54 -    min_cpu = max_cpu = cpu;
  129.55 +    min_stime_cpu = max_stime_cpu = min_cycles_cpu = max_cycles_cpu = cpu;
  129.56      for_each_online_cpu ( cpu )
  129.57      {
  129.58 -        if ( read_clocks_time[cpu] < read_clocks_time[min_cpu] )
  129.59 -            min_cpu = cpu;
  129.60 -        if ( read_clocks_time[cpu] > read_clocks_time[max_cpu] )
  129.61 -            max_cpu = cpu;
  129.62 +        if ( read_clocks_time[cpu] < read_clocks_time[min_stime_cpu] )
  129.63 +            min_stime_cpu = cpu;
  129.64 +        if ( read_clocks_time[cpu] > read_clocks_time[max_stime_cpu] )
  129.65 +            max_stime_cpu = cpu;
  129.66 +        if ( read_cycles_time[cpu] < read_cycles_time[min_cycles_cpu] )
  129.67 +            min_cycles_cpu = cpu;
  129.68 +        if ( read_cycles_time[cpu] > read_cycles_time[max_cycles_cpu] )
  129.69 +            max_cycles_cpu = cpu;
  129.70      }
  129.71  
  129.72 -    min = read_clocks_time[min_cpu];
  129.73 -    max = read_clocks_time[max_cpu];
  129.74 +    min_stime = read_clocks_time[min_stime_cpu];
  129.75 +    max_stime = read_clocks_time[max_stime_cpu];
  129.76 +    min_cycles = read_cycles_time[min_cycles_cpu];
  129.77 +    max_cycles = read_cycles_time[max_cycles_cpu];
  129.78  
  129.79      spin_unlock(&lock);
  129.80  
  129.81 -    dif = difus = max - min;
  129.82 -    do_div(difus, 1000);
  129.83 -    printk("Min = %"PRIu64" ; Max = %"PRIu64" ; Diff = %"PRIu64
  129.84 -           " (%"PRIu64" microseconds)\n",
  129.85 -           min, max, dif, difus);
  129.86 +    dif_stime = max_stime - min_stime;
  129.87 +    if ( dif_stime > maxdif_stime )
  129.88 +        maxdif_stime = dif_stime;
  129.89 +    sumdif_stime += dif_stime;
  129.90 +    dif_cycles = max_cycles - min_cycles;
  129.91 +    if ( dif_cycles > maxdif_cycles )
  129.92 +        maxdif_cycles = dif_cycles;
  129.93 +    sumdif_cycles += dif_cycles;
  129.94 +    count++;
  129.95 +    printk("Synced stime skew: max=%"PRIu64"ns avg=%"PRIu64"ns "
  129.96 +           "samples=%"PRIu32" current=%"PRIu64"ns\n",
  129.97 +           maxdif_stime, sumdif_stime/count, count, dif_stime);
  129.98 +    printk("Synced cycles skew: max=%"PRIu64" avg=%"PRIu64" "
  129.99 +           "samples=%"PRIu32" current=%"PRIu64"\n",
 129.100 +           maxdif_cycles, sumdif_cycles/count, count, dif_cycles);
 129.101  }
 129.102  
 129.103  extern void dump_runq(unsigned char key);
   130.1 --- a/xen/common/page_alloc.c	Thu Aug 07 11:47:34 2008 +0900
   130.2 +++ b/xen/common/page_alloc.c	Thu Aug 07 11:57:34 2008 +0900
   130.3 @@ -53,34 +53,11 @@ static int opt_bootscrub __initdata = 1;
   130.4  boolean_param("bootscrub", opt_bootscrub);
   130.5  
   130.6  /*
   130.7 - * Bit width of the DMA heap.
   130.8 + * Bit width of the DMA heap -- used to override NUMA-node-first.
   130.9 + * allocation strategy, which can otherwise exhaust low memory.
  130.10   */
  130.11 -static unsigned int dma_bitsize = CONFIG_DMA_BITSIZE;
  130.12 -static void __init parse_dma_bits(char *s)
  130.13 -{
  130.14 -    unsigned int v = simple_strtol(s, NULL, 0);
  130.15 -    if ( v >= (BITS_PER_LONG + PAGE_SHIFT) )
  130.16 -        dma_bitsize = BITS_PER_LONG + PAGE_SHIFT;
  130.17 -    else if ( v > PAGE_SHIFT + 1 )
  130.18 -        dma_bitsize = v;
  130.19 -    else
  130.20 -        printk("Invalid dma_bits value of %u ignored.\n", v);
  130.21 -}
  130.22 -custom_param("dma_bits", parse_dma_bits);
  130.23 -
  130.24 -/*
  130.25 - * Amount of memory to reserve in a low-memory (<4GB) pool for specific
  130.26 - * allocation requests. Ordinary requests will not fall back to the
  130.27 - * lowmem emergency pool.
  130.28 - */
  130.29 -static unsigned long dma_emergency_pool_pages;
  130.30 -static void __init parse_dma_emergency_pool(char *s)
  130.31 -{
  130.32 -    unsigned long long bytes;
  130.33 -    bytes = parse_size_and_unit(s, NULL);
  130.34 -    dma_emergency_pool_pages = bytes >> PAGE_SHIFT;
  130.35 -}
  130.36 -custom_param("dma_emergency_pool", parse_dma_emergency_pool);
  130.37 +static unsigned int dma_bitsize;
  130.38 +integer_param("dma_bits", dma_bitsize);
  130.39  
  130.40  #define round_pgdown(_p)  ((_p)&PAGE_MASK)
  130.41  #define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
  130.42 @@ -281,11 +258,7 @@ unsigned long __init alloc_boot_pages(
  130.43   */
  130.44  
  130.45  #define MEMZONE_XEN 0
  130.46 -#ifdef PADDR_BITS
  130.47  #define NR_ZONES    (PADDR_BITS - PAGE_SHIFT)
  130.48 -#else
  130.49 -#define NR_ZONES    (BITS_PER_LONG - PAGE_SHIFT)
  130.50 -#endif
  130.51  
  130.52  #define pfn_dom_zone_type(_pfn) (fls(_pfn) - 1)
  130.53  
  130.54 @@ -583,7 +556,22 @@ void __init end_boot_allocator(void)
  130.55              init_heap_pages(pfn_dom_zone_type(i), mfn_to_page(i), 1);
  130.56      }
  130.57  
  130.58 -    printk("Domain heap initialised: DMA width %u bits\n", dma_bitsize);
  130.59 +    if ( !dma_bitsize && (num_online_nodes() > 1) )
  130.60 +    {
  130.61 +#ifdef CONFIG_X86
  130.62 +        dma_bitsize = min_t(unsigned int,
  130.63 +                            fls(NODE_DATA(0)->node_spanned_pages) - 1
  130.64 +                            + PAGE_SHIFT - 2,
  130.65 +                            32);
  130.66 +#else
  130.67 +        dma_bitsize = 32;
  130.68 +#endif
  130.69 +    }
  130.70 +
  130.71 +    printk("Domain heap initialised");
  130.72 +    if ( dma_bitsize )
  130.73 +        printk(" DMA width %u bits", dma_bitsize);
  130.74 +    printk("\n");
  130.75  }
  130.76  #undef avail_for_domheap
  130.77  
  130.78 @@ -803,20 +791,10 @@ struct page_info *alloc_domheap_pages(
  130.79      if ( bits < zone_hi )
  130.80          zone_hi = bits;
  130.81  
  130.82 -    if ( (zone_hi + PAGE_SHIFT) >= dma_bitsize )
  130.83 -    {
  130.84 +    if ( (dma_bitsize > PAGE_SHIFT) &&
  130.85 +         ((zone_hi + PAGE_SHIFT) >= dma_bitsize) )
  130.86          pg = alloc_heap_pages(dma_bitsize - PAGE_SHIFT, zone_hi, node, order);
  130.87  
  130.88 -        /* Failure? Then check if we can fall back to the DMA pool. */
  130.89 -        if ( unlikely(pg == NULL) &&
  130.90 -             ((order > MAX_ORDER) ||
  130.91 -              (avail_heap_pages(MEMZONE_XEN + 1,
  130.92 -                                dma_bitsize - PAGE_SHIFT - 1,
  130.93 -                                -1) <
  130.94 -               (dma_emergency_pool_pages + (1UL << order)))) )
  130.95 -            return NULL;
  130.96 -    }
  130.97 -
  130.98      if ( (pg == NULL) &&
  130.99           ((pg = alloc_heap_pages(MEMZONE_XEN + 1, zone_hi,
 130.100                                   node, order)) == NULL) )
 130.101 @@ -917,28 +895,15 @@ unsigned long avail_domheap_pages_region
 130.102  
 130.103  unsigned long avail_domheap_pages(void)
 130.104  {
 130.105 -    unsigned long avail_nrm, avail_dma;
 130.106 -    
 130.107 -    avail_nrm = avail_heap_pages(dma_bitsize - PAGE_SHIFT,
 130.108 -                                 NR_ZONES - 1,
 130.109 -                                 -1);
 130.110 -
 130.111 -    avail_dma = avail_heap_pages(MEMZONE_XEN + 1,
 130.112 -                                 dma_bitsize - PAGE_SHIFT - 1,
 130.113 -                                 -1);
 130.114 -
 130.115 -    if ( avail_dma > dma_emergency_pool_pages )
 130.116 -        avail_dma -= dma_emergency_pool_pages;
 130.117 -    else
 130.118 -        avail_dma = 0;
 130.119 -
 130.120 -    return avail_nrm + avail_dma;
 130.121 +    return avail_heap_pages(MEMZONE_XEN + 1,
 130.122 +                            NR_ZONES - 1,
 130.123 +                            -1);
 130.124  }
 130.125  
 130.126  static void pagealloc_keyhandler(unsigned char key)
 130.127  {
 130.128      unsigned int zone = MEMZONE_XEN;
 130.129 -    unsigned long total = 0;
 130.130 +    unsigned long n, total = 0;
 130.131  
 130.132      printk("Physical memory information:\n");
 130.133      printk("    Xen heap: %lukB free\n",
 130.134 @@ -946,9 +911,7 @@ static void pagealloc_keyhandler(unsigne
 130.135  
 130.136      while ( ++zone < NR_ZONES )
 130.137      {
 130.138 -        unsigned long n;
 130.139 -
 130.140 -        if ( zone == dma_bitsize - PAGE_SHIFT )
 130.141 +        if ( (zone + PAGE_SHIFT) == dma_bitsize )
 130.142          {
 130.143              printk("    DMA heap: %lukB free\n", total << (PAGE_SHIFT-10));
 130.144              total = 0;
   131.1 --- a/xen/common/shutdown.c	Thu Aug 07 11:47:34 2008 +0900
   131.2 +++ b/xen/common/shutdown.c	Thu Aug 07 11:57:34 2008 +0900
   131.3 @@ -23,8 +23,7 @@ static void maybe_reboot(void)
   131.4      {
   131.5          printk("rebooting machine in 5 seconds.\n");
   131.6          watchdog_disable();
   131.7 -        mdelay(5000);
   131.8 -        machine_restart();
   131.9 +        machine_restart(5000);
  131.10      }
  131.11  }
  131.12  
  131.13 @@ -50,7 +49,7 @@ void dom0_shutdown(u8 reason)
  131.14      case SHUTDOWN_reboot:
  131.15      {
  131.16          printk("Domain 0 shutdown: rebooting machine.\n");
  131.17 -        machine_restart();
  131.18 +        machine_restart(0);
  131.19          break; /* not reached */
  131.20      }
  131.21  
   132.1 --- a/xen/drivers/char/console.c	Thu Aug 07 11:47:34 2008 +0900
   132.2 +++ b/xen/drivers/char/console.c	Thu Aug 07 11:57:34 2008 +0900
   132.3 @@ -939,8 +939,7 @@ void panic(const char *fmt, ...)
   132.4      else
   132.5      {
   132.6          watchdog_disable();
   132.7 -        mdelay(5000);
   132.8 -        machine_restart();
   132.9 +        machine_restart(5000);
  132.10      }
  132.11  }
  132.12  
   133.1 --- a/xen/drivers/passthrough/amd/iommu_acpi.c	Thu Aug 07 11:47:34 2008 +0900
   133.2 +++ b/xen/drivers/passthrough/amd/iommu_acpi.c	Thu Aug 07 11:57:34 2008 +0900
   133.3 @@ -27,6 +27,7 @@
   133.4  extern unsigned long amd_iommu_page_entries;
   133.5  extern unsigned short ivrs_bdf_entries;
   133.6  extern struct ivrs_mappings *ivrs_mappings;
   133.7 +extern unsigned short last_bdf;
   133.8  
   133.9  static struct amd_iommu * __init find_iommu_from_bdf_cap(
  133.10      u16 bdf, u8 cap_offset)
  133.11 @@ -85,10 +86,8 @@ static void __init reserve_unity_map_for
  133.12      }
  133.13  
  133.14      /* extend r/w permissioms and keep aggregate */
  133.15 -    if ( iw )
  133.16 -        ivrs_mappings[bdf].write_permission = IOMMU_CONTROL_ENABLED;
  133.17 -    if ( ir )
  133.18 -        ivrs_mappings[bdf].read_permission = IOMMU_CONTROL_ENABLED;
  133.19 +    ivrs_mappings[bdf].write_permission = iw;
  133.20 +    ivrs_mappings[bdf].read_permission = ir;
  133.21      ivrs_mappings[bdf].unity_map_enable = IOMMU_CONTROL_ENABLED;
  133.22      ivrs_mappings[bdf].addr_range_start = base;
  133.23      ivrs_mappings[bdf].addr_range_length = length;
  133.24 @@ -112,7 +111,7 @@ static int __init register_exclusion_ran
  133.25          length = range_top - base;
  133.26          /* reserve r/w unity-mapped page entries for devices */
  133.27          /* note: these entries are part of the exclusion range */
  133.28 -        for (bdf = 0; bdf < ivrs_bdf_entries; ++bdf)
  133.29 +        for ( bdf = 0; bdf < ivrs_bdf_entries; bdf++ )
  133.30              reserve_unity_map_for_device(bdf, base, length, iw, ir);
  133.31          /* push 'base' just outside of virtual address space */
  133.32          base = iommu_top;
  133.33 @@ -190,7 +189,7 @@ static int __init register_exclusion_ran
  133.34          length = range_top - base;
  133.35          /* reserve r/w unity-mapped page entries for devices */
  133.36          /* note: these entries are part of the exclusion range */
  133.37 -        for ( bdf = 0; bdf < ivrs_bdf_entries; ++bdf )
  133.38 +        for ( bdf = 0; bdf < ivrs_bdf_entries; bdf++ )
  133.39          {
  133.40              bus = bdf >> 8;
  133.41              devfn = bdf & 0xFF;
  133.42 @@ -357,7 +356,7 @@ static u16 __init parse_ivhd_device_padd
  133.43  }
  133.44  
  133.45  static u16 __init parse_ivhd_device_select(
  133.46 -    union acpi_ivhd_device *ivhd_device)
  133.47 +    union acpi_ivhd_device *ivhd_device, struct amd_iommu *iommu)
  133.48  {
  133.49      u16 bdf;
  133.50  
  133.51 @@ -373,13 +372,14 @@ static u16 __init parse_ivhd_device_sele
  133.52          get_field_from_byte(ivhd_device->header.flags,
  133.53                              AMD_IOMMU_ACPI_SYS_MGT_MASK,
  133.54                              AMD_IOMMU_ACPI_SYS_MGT_SHIFT);
  133.55 +    ivrs_mappings[bdf].iommu = iommu;
  133.56  
  133.57      return sizeof(struct acpi_ivhd_device_header);
  133.58  }
  133.59  
  133.60  static u16 __init parse_ivhd_device_range(
  133.61      union acpi_ivhd_device *ivhd_device,
  133.62 -    u16 header_length, u16 block_length)
  133.63 +    u16 header_length, u16 block_length, struct amd_iommu *iommu)
  133.64  {
  133.65      u16 dev_length, first_bdf, last_bdf, bdf;
  133.66      u8 sys_mgt;
  133.67 @@ -423,14 +423,17 @@ static u16 __init parse_ivhd_device_rang
  133.68                                    AMD_IOMMU_ACPI_SYS_MGT_MASK,
  133.69                                    AMD_IOMMU_ACPI_SYS_MGT_SHIFT);
  133.70      for ( bdf = first_bdf; bdf <= last_bdf; bdf++ )
  133.71 +    {
  133.72          ivrs_mappings[bdf].dte_sys_mgt_enable = sys_mgt;
  133.73 +        ivrs_mappings[bdf].iommu = iommu;
  133.74 +    }
  133.75  
  133.76      return dev_length;
  133.77  }
  133.78  
  133.79  static u16 __init parse_ivhd_device_alias(
  133.80      union acpi_ivhd_device *ivhd_device,
  133.81 -    u16 header_length, u16 block_length)
  133.82 +    u16 header_length, u16 block_length, struct amd_iommu *iommu)
  133.83  {
  133.84      u16 dev_length, alias_id, bdf;
  133.85  
  133.86 @@ -463,15 +466,18 @@ static u16 __init parse_ivhd_device_alia
  133.87          get_field_from_byte(ivhd_device->header.flags,
  133.88                              AMD_IOMMU_ACPI_SYS_MGT_MASK,
  133.89                              AMD_IOMMU_ACPI_SYS_MGT_SHIFT);
  133.90 +    ivrs_mappings[bdf].iommu = iommu;
  133.91 +
  133.92      ivrs_mappings[alias_id].dte_sys_mgt_enable =
  133.93          ivrs_mappings[bdf].dte_sys_mgt_enable;
  133.94 +    ivrs_mappings[alias_id].iommu = iommu;
  133.95  
  133.96      return dev_length;
  133.97  }
  133.98  
  133.99  static u16 __init parse_ivhd_device_alias_range(
 133.100      union acpi_ivhd_device *ivhd_device,
 133.101 -    u16 header_length, u16 block_length)
 133.102 +    u16 header_length, u16 block_length, struct amd_iommu *iommu)
 133.103  {
 133.104  
 133.105      u16 dev_length, first_bdf, last_bdf, alias_id, bdf;
 133.106 @@ -527,15 +533,17 @@ static u16 __init parse_ivhd_device_alia
 133.107      {
 133.108          ivrs_mappings[bdf].dte_requestor_id = alias_id;
 133.109          ivrs_mappings[bdf].dte_sys_mgt_enable = sys_mgt;
 133.110 +        ivrs_mappings[bdf].iommu = iommu;
 133.111      }
 133.112      ivrs_mappings[alias_id].dte_sys_mgt_enable = sys_mgt;
 133.113 +    ivrs_mappings[alias_id].iommu = iommu;
 133.114  
 133.115      return dev_length;
 133.116  }
 133.117  
 133.118  static u16 __init parse_ivhd_device_extended(
 133.119      union acpi_ivhd_device *ivhd_device,
 133.120 -    u16 header_length, u16 block_length)
 133.121 +    u16 header_length, u16 block_length, struct amd_iommu *iommu)
 133.122  {
 133.123      u16 dev_length, bdf;
 133.124  
 133.125 @@ -558,13 +566,14 @@ static u16 __init parse_ivhd_device_exte
 133.126          get_field_from_byte(ivhd_device->header.flags,
 133.127                              AMD_IOMMU_ACPI_SYS_MGT_MASK,
 133.128                              AMD_IOMMU_ACPI_SYS_MGT_SHIFT);
 133.129 +    ivrs_mappings[bdf].iommu = iommu;
 133.130  
 133.131      return dev_length;
 133.132  }
 133.133  
 133.134  static u16 __init parse_ivhd_device_extended_range(
 133.135      union acpi_ivhd_device *ivhd_device,
 133.136 -    u16 header_length, u16 block_length)
 133.137 +    u16 header_length, u16 block_length, struct amd_iommu *iommu)
 133.138  {
 133.139      u16 dev_length, first_bdf, last_bdf, bdf;
 133.140      u8 sys_mgt;
 133.141 @@ -609,7 +618,10 @@ static u16 __init parse_ivhd_device_exte
 133.142                                    AMD_IOMMU_ACPI_SYS_MGT_MASK,
 133.143                                    AMD_IOMMU_ACPI_SYS_MGT_SHIFT);
 133.144      for ( bdf = first_bdf; bdf <= last_bdf; bdf++ )
 133.145 +    {
 133.146          ivrs_mappings[bdf].dte_sys_mgt_enable = sys_mgt;
 133.147 +        ivrs_mappings[bdf].iommu = iommu;
 133.148 +    }
 133.149  
 133.150      return dev_length;
 133.151  }
 133.152 @@ -636,33 +648,6 @@ static int __init parse_ivhd_block(struc
 133.153          return -ENODEV;
 133.154      }
 133.155  
 133.156 -    amd_iov_info("IVHD Block:\n");
 133.157 -    amd_iov_info(" Cap_Offset 0x%x\n", ivhd_block->cap_offset);
 133.158 -    amd_iov_info(" MMIO_BAR_Phys 0x%"PRIx64"\n",ivhd_block->mmio_base);
 133.159 -    amd_iov_info( " PCI_Segment 0x%x\n", ivhd_block->pci_segment);
 133.160 -    amd_iov_info( " IOMMU_Info 0x%x\n", ivhd_block->iommu_info);
 133.161 -
 133.162 -    /* override IOMMU support flags */
 133.163 -    iommu->coherent = get_field_from_byte(ivhd_block->header.flags,
 133.164 -                                          AMD_IOMMU_ACPI_COHERENT_MASK,
 133.165 -                                          AMD_IOMMU_ACPI_COHERENT_SHIFT);
 133.166 -    iommu->iotlb_support = get_field_from_byte(ivhd_block->header.flags,
 133.167 -                                               AMD_IOMMU_ACPI_IOTLB_SUP_MASK,
 133.168 -                                               AMD_IOMMU_ACPI_IOTLB_SUP_SHIFT);
 133.169 -    iommu->isochronous = get_field_from_byte(ivhd_block->header.flags,
 133.170 -                                             AMD_IOMMU_ACPI_ISOC_MASK,
 133.171 -                                             AMD_IOMMU_ACPI_ISOC_SHIFT);
 133.172 -    iommu->res_pass_pw = get_field_from_byte(ivhd_block->header.flags,
 133.173 -                                             AMD_IOMMU_ACPI_RES_PASS_PW_MASK,
 133.174 -                                             AMD_IOMMU_ACPI_RES_PASS_PW_SHIFT);
 133.175 -    iommu->pass_pw = get_field_from_byte(ivhd_block->header.flags,
 133.176 -                                         AMD_IOMMU_ACPI_PASS_PW_MASK,
 133.177 -                                         AMD_IOMMU_ACPI_PASS_PW_SHIFT);
 133.178 -    iommu->ht_tunnel_enable = get_field_from_byte(
 133.179 -        ivhd_block->header.flags,
 133.180 -        AMD_IOMMU_ACPI_HT_TUN_ENB_MASK,
 133.181 -        AMD_IOMMU_ACPI_HT_TUN_ENB_SHIFT);
 133.182 -
 133.183      /* parse Device Entries */
 133.184      block_length = sizeof(struct acpi_ivhd_block_header);
 133.185      while ( ivhd_block->header.length >=
 133.186 @@ -689,32 +674,32 @@ static int __init parse_ivhd_block(struc
 133.187                  ivhd_block->header.length, block_length);
 133.188              break;
 133.189          case AMD_IOMMU_ACPI_IVHD_DEV_SELECT:
 133.190 -            dev_length = parse_ivhd_device_select(ivhd_device);
 133.191 +            dev_length = parse_ivhd_device_select(ivhd_device, iommu);
 133.192              break;
 133.193          case AMD_IOMMU_ACPI_IVHD_DEV_RANGE_START:
 133.194              dev_length = parse_ivhd_device_range(
 133.195                  ivhd_device,
 133.196 -                ivhd_block->header.length, block_length);
 133.197 +                ivhd_block->header.length, block_length, iommu);
 133.198              break;
 133.199          case AMD_IOMMU_ACPI_IVHD_DEV_ALIAS_SELECT:
 133.200              dev_length = parse_ivhd_device_alias(
 133.201                  ivhd_device,
 133.202 -                ivhd_block->header.length, block_length);
 133.203 +                ivhd_block->header.length, block_length, iommu);
 133.204              break;
 133.205          case AMD_IOMMU_ACPI_IVHD_DEV_ALIAS_RANGE:
 133.206              dev_length = parse_ivhd_device_alias_range(
 133.207                  ivhd_device,
 133.208 -                ivhd_block->header.length, block_length);
 133.209 +                ivhd_block->header.length, block_length, iommu);
 133.210              break;
 133.211          case AMD_IOMMU_ACPI_IVHD_DEV_EXT_SELECT:
 133.212              dev_length = parse_ivhd_device_extended(
 133.213                  ivhd_device,
 133.214 -                ivhd_block->header.length, block_length);
 133.215 +                ivhd_block->header.length, block_length, iommu);
 133.216              break;
 133.217          case AMD_IOMMU_ACPI_IVHD_DEV_EXT_RANGE:
 133.218              dev_length = parse_ivhd_device_extended_range(
 133.219                  ivhd_device,
 133.220 -                ivhd_block->header.length, block_length);
 133.221 +                ivhd_block->header.length, block_length, iommu);
 133.222              break;
 133.223          default:
 133.224              amd_iov_error("IVHD Error: Invalid Device Type!\n");
 133.225 @@ -794,11 +779,10 @@ static void __init dump_acpi_table_heade
 133.226  
 133.227  }
 133.228  
 133.229 -int __init parse_ivrs_table(struct acpi_table_header *_table)
 133.230 +static int __init parse_ivrs_table(struct acpi_table_header *_table)
 133.231  {
 133.232      struct acpi_ivrs_block_header *ivrs_block;
 133.233 -    unsigned long length, i;
 133.234 -    u8 checksum, *raw_table;
 133.235 +    unsigned long length;
 133.236      int error = 0;
 133.237      struct acpi_table_header *table = (struct acpi_table_header *)_table;
 133.238  
 133.239 @@ -806,18 +790,6 @@ int __init parse_ivrs_table(struct acpi_
 133.240  
 133.241      dump_acpi_table_header(table);
 133.242  
 133.243 -    /* validate checksum: sum of entire table == 0 */
 133.244 -    checksum = 0;
 133.245 -    raw_table = (u8 *)table;
 133.246 -    for ( i = 0; i < table->length; i++ )
 133.247 -        checksum += raw_table[i];
 133.248 -    if ( checksum )
 133.249 -    {
 133.250 -        amd_iov_error("IVRS Error: "
 133.251 -                "Invalid Checksum 0x%x\n", checksum);
 133.252 -        return -ENODEV;
 133.253 -    }
 133.254 -
 133.255      /* parse IVRS blocks */
 133.256      length = sizeof(struct acpi_ivrs_table_header);
 133.257      while ( (error == 0) && (table->length > (length + sizeof(*ivrs_block))) )
 133.258 @@ -846,3 +818,144 @@ int __init parse_ivrs_table(struct acpi_
 133.259  
 133.260      return error;
 133.261  }
 133.262 +
 133.263 +static int __init detect_iommu_acpi(struct acpi_table_header *_table)
 133.264 +{
 133.265 +    struct acpi_ivrs_block_header *ivrs_block;
 133.266 +    struct acpi_table_header *table = (struct acpi_table_header *)_table;
 133.267 +    unsigned long i;
 133.268 +    unsigned long length = sizeof(struct acpi_ivrs_table_header);
 133.269 +    u8 checksum, *raw_table;
 133.270 +
 133.271 +    /* validate checksum: sum of entire table == 0 */
 133.272 +    checksum = 0;
 133.273 +    raw_table = (u8 *)table;
 133.274 +    for ( i = 0; i < table->length; i++ )
 133.275 +        checksum += raw_table[i];
 133.276 +    if ( checksum )
 133.277 +    {
 133.278 +        amd_iov_error("IVRS Error: "
 133.279 +                "Invalid Checksum 0x%x\n", checksum);
 133.280 +        return -ENODEV;
 133.281 +    }
 133.282 +
 133.283 +    while ( table->length > (length + sizeof(*ivrs_block)) )
 133.284 +    {
 133.285 +        ivrs_block = (struct acpi_ivrs_block_header *) ((u8 *)table + length);
 133.286 +        if ( table->length < (length + ivrs_block->length) )
 133.287 +            return -ENODEV;
 133.288 +        if ( ivrs_block->type == AMD_IOMMU_ACPI_IVHD_TYPE )
 133.289 +            if ( amd_iommu_detect_one_acpi((void*)ivrs_block) != 0 )
 133.290 +                return -ENODEV;
 133.291 +        length += ivrs_block->length;
 133.292 +    }
 133.293 +    return 0;
 133.294 +}
 133.295 +
 133.296 +#define UPDATE_LAST_BDF(x) do {\
 133.297 +   if ((x) > last_bdf) \
 133.298 +       last_bdf = (x); \
 133.299 +   } while(0);
 133.300 +
 133.301 +static int __init get_last_bdf_ivhd(void *ivhd)
 133.302 +{
 133.303 +    union acpi_ivhd_device *ivhd_device;
 133.304 +    u16 block_length, dev_length;
 133.305 +    struct acpi_ivhd_block_header *ivhd_block;
 133.306 +
 133.307 +    ivhd_block = (struct acpi_ivhd_block_header *)ivhd;
 133.308 +
 133.309 +    if ( ivhd_block->header.length <
 133.310 +         sizeof(struct acpi_ivhd_block_header) )
 133.311 +    {
 133.312 +        amd_iov_error("IVHD Error: Invalid Block Length!\n");
 133.313 +        return -ENODEV;
 133.314 +    }
 133.315 +
 133.316 +    block_length = sizeof(struct acpi_ivhd_block_header);
 133.317 +    while ( ivhd_block->header.length >=
 133.318 +            (block_length + sizeof(struct acpi_ivhd_device_header)) )
 133.319 +    {
 133.320 +        ivhd_device = (union acpi_ivhd_device *)
 133.321 +            ((u8 *)ivhd_block + block_length);
 133.322 +
 133.323 +        switch ( ivhd_device->header.type )
 133.324 +        {
 133.325 +        case AMD_IOMMU_ACPI_IVHD_DEV_U32_PAD:
 133.326 +            dev_length = sizeof(u32);
 133.327 +            break;
 133.328 +        case AMD_IOMMU_ACPI_IVHD_DEV_U64_PAD:
 133.329 +            dev_length = sizeof(u64);
 133.330 +            break;
 133.331 +        case AMD_IOMMU_ACPI_IVHD_DEV_SELECT:
 133.332 +            UPDATE_LAST_BDF(ivhd_device->header.dev_id);
 133.333 +            dev_length = sizeof(struct acpi_ivhd_device_header);
 133.334 +            break;
 133.335 +        case AMD_IOMMU_ACPI_IVHD_DEV_ALIAS_SELECT:
 133.336 +            UPDATE_LAST_BDF(ivhd_device->header.dev_id);
 133.337 +            dev_length = sizeof(struct acpi_ivhd_device_alias);
 133.338 +            break;
 133.339 +        case AMD_IOMMU_ACPI_IVHD_DEV_EXT_SELECT:
 133.340 +            UPDATE_LAST_BDF(ivhd_device->header.dev_id);
 133.341 +            dev_length = sizeof(struct acpi_ivhd_device_extended);
 133.342 +            break;
 133.343 +        case AMD_IOMMU_ACPI_IVHD_DEV_RANGE_START:
 133.344 +            UPDATE_LAST_BDF(ivhd_device->range.trailer.dev_id);
 133.345 +            dev_length = sizeof(struct acpi_ivhd_device_range);
 133.346 +            break;
 133.347 +        case AMD_IOMMU_ACPI_IVHD_DEV_ALIAS_RANGE:
 133.348 +            UPDATE_LAST_BDF(ivhd_device->alias_range.trailer.dev_id)
 133.349 +            dev_length = sizeof(struct acpi_ivhd_device_alias_range);
 133.350 +            break;
 133.351 +        case AMD_IOMMU_ACPI_IVHD_DEV_EXT_RANGE:
 133.352 +            UPDATE_LAST_BDF(ivhd_device->extended_range.trailer.dev_id)
 133.353 +            dev_length = sizeof(struct acpi_ivhd_device_extended_range);
 133.354 +            break;
 133.355 +        default:
 133.356 +            amd_iov_error("IVHD Error: Invalid Device Type!\n");
 133.357 +            dev_length = 0;
 133.358 +            break;
 133.359 +        }
 133.360 +
 133.361 +        block_length += dev_length;
 133.362 +        if ( !dev_length )
 133.363 +            return -ENODEV;
 133.364 +    }
 133.365 +
 133.366 +    return 0;
 133.367 +}
 133.368 +
 133.369 +static int __init get_last_bdf_acpi(struct acpi_table_header *_table)
 133.370 +{
 133.371 +    struct acpi_ivrs_block_header *ivrs_block;
 133.372 +    struct acpi_table_header *table = (struct acpi_table_header *)_table;
 133.373 +    unsigned long length = sizeof(struct acpi_ivrs_table_header);
 133.374 +
 133.375 +    while ( table->length > (length + sizeof(*ivrs_block)) )
 133.376 +    {
 133.377 +        ivrs_block = (struct acpi_ivrs_block_header *) ((u8 *)table + length);
 133.378 +        if ( table->length < (length + ivrs_block->length) )
 133.379 +            return -ENODEV;
 133.380 +        if ( ivrs_block->type == AMD_IOMMU_ACPI_IVHD_TYPE )
 133.381 +            if ( get_last_bdf_ivhd((void*)ivrs_block) != 0 )
 133.382 +                return -ENODEV;
 133.383 +        length += ivrs_block->length;
 133.384 +    }
 133.385 +   return 0;
 133.386 +}
 133.387 +
 133.388 +int __init amd_iommu_detect_acpi(void)
 133.389 +{
 133.390 +    return acpi_table_parse(AMD_IOMMU_ACPI_IVRS_SIG, detect_iommu_acpi);
 133.391 +}
 133.392 +
 133.393 +int __init amd_iommu_get_ivrs_dev_entries(void)
 133.394 +{
 133.395 +    acpi_table_parse(AMD_IOMMU_ACPI_IVRS_SIG, get_last_bdf_acpi);
 133.396 +    return last_bdf + 1;
 133.397 +}
 133.398 +
 133.399 +int __init amd_iommu_update_ivrs_mapping_acpi(void)
 133.400 +{
 133.401 +    return acpi_table_parse(AMD_IOMMU_ACPI_IVRS_SIG, parse_ivrs_table);
 133.402 +}
   134.1 --- a/xen/drivers/passthrough/amd/iommu_detect.c	Thu Aug 07 11:47:34 2008 +0900
   134.2 +++ b/xen/drivers/passthrough/amd/iommu_detect.c	Thu Aug 07 11:57:34 2008 +0900
   134.3 @@ -25,65 +25,10 @@
   134.4  #include <xen/pci_regs.h>
   134.5  #include <asm/amd-iommu.h>
   134.6  #include <asm/hvm/svm/amd-iommu-proto.h>
   134.7 -
   134.8 -static int __init valid_bridge_bus_config(
   134.9 -    int bus, int dev, int func, int *sec_bus, int *sub_bus)
  134.10 -{
  134.11 -    int pri_bus;
  134.12 -
  134.13 -    pri_bus = pci_conf_read8(bus, dev, func, PCI_PRIMARY_BUS);
  134.14 -    *sec_bus = pci_conf_read8(bus, dev, func, PCI_SECONDARY_BUS);
  134.15 -    *sub_bus = pci_conf_read8(bus, dev, func, PCI_SUBORDINATE_BUS);
  134.16 -
  134.17 -    return ((pri_bus == bus) && (*sec_bus > bus) && (*sub_bus >= *sec_bus));
  134.18 -}
  134.19 -
  134.20 -int __init get_iommu_last_downstream_bus(struct amd_iommu *iommu)
  134.21 -{
  134.22 -    int bus, dev, func;
  134.23 -    int devfn, hdr_type;
  134.24 -    int sec_bus, sub_bus;
  134.25 -    int multi_func;
  134.26 +#include <asm/hvm/svm/amd-iommu-acpi.h>
  134.27  
  134.28 -    bus = iommu->last_downstream_bus = iommu->root_bus;
  134.29 -    iommu->downstream_bus_present[bus] = 1;
  134.30 -    dev = PCI_SLOT(iommu->first_devfn);
  134.31 -    multi_func = PCI_FUNC(iommu->first_devfn) > 0;
  134.32 -    for ( devfn = iommu->first_devfn; devfn <= iommu->last_devfn; devfn++ )
  134.33 -    {
  134.34 -        /* skipping to next device#? */
  134.35 -        if ( dev != PCI_SLOT(devfn) )
  134.36 -        {
  134.37 -            dev = PCI_SLOT(devfn);
  134.38 -            multi_func = 0;
  134.39 -        }
  134.40 -        func = PCI_FUNC(devfn);
  134.41 - 
  134.42 -        if ( !VALID_PCI_VENDOR_ID(pci_conf_read16(bus, dev, func,
  134.43 -                                                  PCI_VENDOR_ID)) )
  134.44 -            continue;
  134.45 -
  134.46 -        hdr_type = pci_conf_read8(bus, dev, func, PCI_HEADER_TYPE);
  134.47 -        if ( func == 0 )
  134.48 -            multi_func = IS_PCI_MULTI_FUNCTION(hdr_type);
  134.49 -
  134.50 -        if ( (func == 0 || multi_func) &&
  134.51 -             IS_PCI_TYPE1_HEADER(hdr_type) )
  134.52 -        {
  134.53 -            if ( !valid_bridge_bus_config(bus, dev, func,
  134.54 -                                          &sec_bus, &sub_bus) )
  134.55 -                return -ENODEV;
  134.56 -
  134.57 -            if ( sub_bus > iommu->last_downstream_bus )
  134.58 -                iommu->last_downstream_bus = sub_bus;
  134.59 -            do {
  134.60 -                iommu->downstream_bus_present[sec_bus] = 1;
  134.61 -            } while ( sec_bus++ < sub_bus );
  134.62 -        }
  134.63 -    }
  134.64 -
  134.65 -    return 0;
  134.66 -}
  134.67 +extern struct list_head amd_iommu_head;
  134.68 +unsigned short last_bdf = 0;
  134.69  
  134.70  static int __init get_iommu_msi_capabilities(u8 bus, u8 dev, u8 func,
  134.71              struct amd_iommu *iommu)
  134.72 @@ -128,30 +73,10 @@ int __init get_iommu_capabilities(u8 bus
  134.73                                    struct amd_iommu *iommu)
  134.74  {
  134.75      u32 cap_header, cap_range, misc_info;
  134.76 -    u64 mmio_bar;
  134.77 -
  134.78 -    mmio_bar = (u64)pci_conf_read32(
  134.79 -        bus, dev, func, cap_ptr + PCI_CAP_MMIO_BAR_HIGH_OFFSET) << 32;
  134.80 -    mmio_bar |= pci_conf_read32(bus, dev, func,
  134.81 -                                cap_ptr + PCI_CAP_MMIO_BAR_LOW_OFFSET);
  134.82 -    iommu->mmio_base_phys = mmio_bar & (u64)~0x3FFF;
  134.83 -
  134.84 -    if ( ((mmio_bar & 0x1) == 0) || (iommu->mmio_base_phys == 0) )
  134.85 -    {
  134.86 -        amd_iov_error("Invalid MMIO_BAR = 0x%"PRIx64"\n", mmio_bar);
  134.87 -        return -ENODEV;
  134.88 -    }
  134.89 -
  134.90 -    iommu->bdf = (bus << 8) | PCI_DEVFN(dev, func);
  134.91 -    iommu->cap_offset = cap_ptr;
  134.92  
  134.93      cap_header = pci_conf_read32(bus, dev, func, cap_ptr);
  134.94      iommu->revision = get_field_from_reg_u32(
  134.95          cap_header, PCI_CAP_REV_MASK, PCI_CAP_REV_SHIFT);
  134.96 -    iommu->iotlb_support = get_field_from_reg_u32(
  134.97 -        cap_header, PCI_CAP_IOTLB_MASK, PCI_CAP_IOTLB_SHIFT);
  134.98 -    iommu->ht_tunnel_support = get_field_from_reg_u32(
  134.99 -        cap_header, PCI_CAP_HT_TUNNEL_MASK, PCI_CAP_HT_TUNNEL_SHIFT);
 134.100      iommu->pte_not_present_cached = get_field_from_reg_u32(
 134.101          cap_header, PCI_CAP_NP_CACHE_MASK, PCI_CAP_NP_CACHE_SHIFT);
 134.102  
 134.103 @@ -159,96 +84,76 @@ int __init get_iommu_capabilities(u8 bus
 134.104                                  cap_ptr + PCI_CAP_RANGE_OFFSET);
 134.105      iommu->unit_id = get_field_from_reg_u32(
 134.106          cap_range, PCI_CAP_UNIT_ID_MASK, PCI_CAP_UNIT_ID_SHIFT);
 134.107 -    iommu->root_bus = get_field_from_reg_u32(
 134.108 -        cap_range, PCI_CAP_BUS_NUMBER_MASK, PCI_CAP_BUS_NUMBER_SHIFT);
 134.109 -    iommu->first_devfn = get_field_from_reg_u32(
 134.110 -        cap_range, PCI_CAP_FIRST_DEVICE_MASK, PCI_CAP_FIRST_DEVICE_SHIFT);
 134.111 -    iommu->last_devfn = get_field_from_reg_u32(
 134.112 -        cap_range, PCI_CAP_LAST_DEVICE_MASK, PCI_CAP_LAST_DEVICE_SHIFT);
 134.113  
 134.114      misc_info = pci_conf_read32(bus, dev, func,
 134.115                                  cap_ptr + PCI_MISC_INFO_OFFSET);
 134.116      iommu->msi_number = get_field_from_reg_u32(
 134.117          misc_info, PCI_CAP_MSI_NUMBER_MASK, PCI_CAP_MSI_NUMBER_SHIFT);
 134.118  
 134.119 -    get_iommu_msi_capabilities(bus, dev, func, iommu);
 134.120 -
 134.121      return 0;
 134.122  }
 134.123  
 134.124 -static int __init scan_caps_for_iommu(
 134.125 -    int bus, int dev, int func,
 134.126 -    iommu_detect_callback_ptr_t iommu_detect_callback)
 134.127 +int __init amd_iommu_detect_one_acpi(void *ivhd)
 134.128  {
 134.129 -    int cap_ptr, cap_id, cap_type;
 134.130 -    u32 cap_header;
 134.131 -    int count, error = 0;
 134.132 +    struct amd_iommu *iommu;
 134.133 +    u8 bus, dev, func;
 134.134 +    struct acpi_ivhd_block_header *ivhd_block;
 134.135  
 134.136 -    count = 0;
 134.137 -    cap_ptr = pci_conf_read8(bus, dev, func, PCI_CAPABILITY_LIST);
 134.138 -    while ( (cap_ptr >= PCI_MIN_CAP_OFFSET) &&
 134.139 -            (count < PCI_MAX_CAP_BLOCKS) &&
 134.140 -            !error )
 134.141 +    ivhd_block = (struct acpi_ivhd_block_header *)ivhd;
 134.142 +
 134.143 +    if ( ivhd_block->header.length < sizeof(struct acpi_ivhd_block_header) )
 134.144      {
 134.145 -        cap_ptr &= PCI_CAP_PTR_MASK;
 134.146 -        cap_header = pci_conf_read32(bus, dev, func, cap_ptr);
 134.147 -        cap_id = get_field_from_reg_u32(
 134.148 -            cap_header, PCI_CAP_ID_MASK, PCI_CAP_ID_SHIFT);
 134.149 +        amd_iov_error("Invalid IVHD Block Length!\n");
 134.150 +        return -ENODEV;
 134.151 +    }
 134.152  
 134.153 -        if ( cap_id == PCI_CAP_ID_SECURE_DEVICE )
 134.154 -        {
 134.155 -            cap_type = get_field_from_reg_u32(
 134.156 -                cap_header, PCI_CAP_TYPE_MASK, PCI_CAP_TYPE_SHIFT);
 134.157 -            if ( cap_type == PCI_CAP_TYPE_IOMMU )
 134.158 -                error = iommu_detect_callback(
 134.159 -                    bus, dev, func, cap_ptr);
 134.160 -        }
 134.161 -
 134.162 -        cap_ptr = get_field_from_reg_u32(
 134.163 -            cap_header, PCI_CAP_NEXT_PTR_MASK, PCI_CAP_NEXT_PTR_SHIFT);
 134.164 -        count++;
 134.165 +    if ( !ivhd_block->header.dev_id ||
 134.166 +        !ivhd_block->cap_offset || !ivhd_block->mmio_base)
 134.167 +    {
 134.168 +        amd_iov_error("Invalid IVHD Block!\n");
 134.169 +        return -ENODEV;
 134.170      }
 134.171  
 134.172 -    return error;
 134.173 -}
 134.174 -
 134.175 -static int __init scan_functions_for_iommu(
 134.176 -    int bus, int dev, iommu_detect_callback_ptr_t iommu_detect_callback)
 134.177 -{
 134.178 -    int func, hdr_type;
 134.179 -    int count = 1, error = 0;
 134.180 +    iommu = (struct amd_iommu *) xmalloc(struct amd_iommu);
 134.181 +    if ( !iommu )
 134.182 +    {
 134.183 +        amd_iov_error("Error allocating amd_iommu\n");
 134.184 +        return -ENOMEM;
 134.185 +    }
 134.186 +    memset(iommu, 0, sizeof(struct amd_iommu));
 134.187  
 134.188 -    for ( func = 0;
 134.189 -          (func < count) && !error &&
 134.190 -              VALID_PCI_VENDOR_ID(pci_conf_read16(bus, dev, func,
 134.191 -                                                  PCI_VENDOR_ID));
 134.192 -          func++ )
 134.193 +    spin_lock_init(&iommu->lock);
 134.194  
 134.195 -    {
 134.196 -        hdr_type = pci_conf_read8(bus, dev, func, PCI_HEADER_TYPE);
 134.197 -
 134.198 -        if ( (func == 0) && IS_PCI_MULTI_FUNCTION(hdr_type) )
 134.199 -            count = PCI_MAX_FUNC_COUNT;
 134.200 +    iommu->bdf = ivhd_block->header.dev_id;
 134.201 +    iommu->cap_offset = ivhd_block->cap_offset;
 134.202 +    iommu->mmio_base_phys = ivhd_block->mmio_base;
 134.203  
 134.204 -        if ( IS_PCI_TYPE0_HEADER(hdr_type) ||
 134.205 -             IS_PCI_TYPE1_HEADER(hdr_type) )
 134.206 -            error = scan_caps_for_iommu(bus, dev, func,
 134.207 -                                        iommu_detect_callback);
 134.208 -    }
 134.209 -
 134.210 -    return error;
 134.211 -}
 134.212 -
 134.213 +    /* override IOMMU support flags */
 134.214 +    iommu->coherent = get_field_from_byte(ivhd_block->header.flags,
 134.215 +                        AMD_IOMMU_ACPI_COHERENT_MASK,
 134.216 +                        AMD_IOMMU_ACPI_COHERENT_SHIFT);
 134.217 +    iommu->iotlb_support = get_field_from_byte(ivhd_block->header.flags,
 134.218 +                        AMD_IOMMU_ACPI_IOTLB_SUP_MASK,
 134.219 +                        AMD_IOMMU_ACPI_IOTLB_SUP_SHIFT);
 134.220 +    iommu->isochronous = get_field_from_byte(ivhd_block->header.flags,
 134.221 +                        AMD_IOMMU_ACPI_ISOC_MASK,
 134.222 +                        AMD_IOMMU_ACPI_ISOC_SHIFT);
 134.223 +    iommu->res_pass_pw = get_field_from_byte(ivhd_block->header.flags,
 134.224 +                        AMD_IOMMU_ACPI_RES_PASS_PW_MASK,
 134.225 +                        AMD_IOMMU_ACPI_RES_PASS_PW_SHIFT);
 134.226 +    iommu->pass_pw = get_field_from_byte(ivhd_block->header.flags,
 134.227 +                        AMD_IOMMU_ACPI_PASS_PW_MASK,
 134.228 +                        AMD_IOMMU_ACPI_PASS_PW_SHIFT);
 134.229 +    iommu->ht_tunnel_enable = get_field_from_byte(ivhd_block->header.flags,
 134.230 +                        AMD_IOMMU_ACPI_HT_TUN_ENB_MASK,
 134.231 +                        AMD_IOMMU_ACPI_HT_TUN_ENB_SHIFT);
 134.232 +    bus = iommu->bdf >> 8;
 134.233 +    dev = PCI_SLOT(iommu->bdf & 0xFF);
 134.234 +    func = PCI_FUNC(iommu->bdf & 0xFF);
 134.235 +    get_iommu_capabilities(bus, dev, func, iommu->cap_offset, iommu);
 134.236 +    get_iommu_msi_capabilities(bus, dev, func, iommu);
 134.237  
 134.238 -int __init scan_for_iommu(iommu_detect_callback_ptr_t iommu_detect_callback)
 134.239 -{
 134.240 -    int bus, dev, error = 0;
 134.241 +    list_add_tail(&iommu->list, &amd_iommu_head);
 134.242  
 134.243 -    for ( bus = 0; bus < PCI_MAX_BUS_COUNT && !error; ++bus )
 134.244 -        for ( dev = 0; dev < PCI_MAX_DEV_COUNT && !error; ++dev )
 134.245 -            error = scan_functions_for_iommu(bus, dev,
 134.246 -                                             iommu_detect_callback);
 134.247 -
 134.248 -    return error;
 134.249 +    return 0;
 134.250  }
 134.251 -
   135.1 --- a/xen/drivers/passthrough/amd/iommu_init.c	Thu Aug 07 11:47:34 2008 +0900
   135.2 +++ b/xen/drivers/passthrough/amd/iommu_init.c	Thu Aug 07 11:57:34 2008 +0900
   135.3 @@ -27,10 +27,20 @@
   135.4  #include <asm/hvm/svm/amd-iommu-proto.h>
   135.5  #include <asm-x86/fixmap.h>
   135.6  
   135.7 -extern int nr_amd_iommus;
   135.8  static struct amd_iommu *vector_to_iommu[NR_VECTORS];
   135.9 +static int nr_amd_iommus;
  135.10 +static long amd_iommu_cmd_buffer_entries = IOMMU_CMD_BUFFER_DEFAULT_ENTRIES;
  135.11 +static long amd_iommu_event_log_entries = IOMMU_EVENT_LOG_DEFAULT_ENTRIES;
  135.12  
  135.13 -int __init map_iommu_mmio_region(struct amd_iommu *iommu)
  135.14 +unsigned short ivrs_bdf_entries;
  135.15 +struct ivrs_mappings *ivrs_mappings;
  135.16 +struct list_head amd_iommu_head;
  135.17 +struct table_struct device_table;
  135.18 +
  135.19 +extern void *int_remap_table;
  135.20 +extern spinlock_t int_remap_table_lock;
  135.21 +
  135.22 +static int __init map_iommu_mmio_region(struct amd_iommu *iommu)
  135.23  {
  135.24      unsigned long mfn;
  135.25  
  135.26 @@ -51,7 +61,7 @@ int __init map_iommu_mmio_region(struct 
  135.27      return 0;
  135.28  }
  135.29  
  135.30 -void __init unmap_iommu_mmio_region(struct amd_iommu *iommu)
  135.31 +static void __init unmap_iommu_mmio_region(struct amd_iommu *iommu)
  135.32  {
  135.33      if ( iommu->mmio_base )
  135.34      {
  135.35 @@ -60,7 +70,7 @@ void __init unmap_iommu_mmio_region(stru
  135.36      }
  135.37  }
  135.38  
  135.39 -void __init register_iommu_dev_table_in_mmio_space(struct amd_iommu *iommu)
  135.40 +static void __init register_iommu_dev_table_in_mmio_space(struct amd_iommu *iommu)
  135.41  {
  135.42      u64 addr_64, addr_lo, addr_hi;
  135.43      u32 entry;
  135.44 @@ -83,7 +93,7 @@ void __init register_iommu_dev_table_in_
  135.45      writel(entry, iommu->mmio_base + IOMMU_DEV_TABLE_BASE_HIGH_OFFSET);
  135.46  }
  135.47  
  135.48 -void __init register_iommu_cmd_buffer_in_mmio_space(struct amd_iommu *iommu)
  135.49 +static void __init register_iommu_cmd_buffer_in_mmio_space(struct amd_iommu *iommu)
  135.50  {
  135.51      u64 addr_64, addr_lo, addr_hi;
  135.52      u32 power_of2_entries;
  135.53 @@ -110,7 +120,7 @@ void __init register_iommu_cmd_buffer_in
  135.54      writel(entry, iommu->mmio_base+IOMMU_CMD_BUFFER_BASE_HIGH_OFFSET);
  135.55  }
  135.56  
  135.57 -void __init register_iommu_event_log_in_mmio_space(struct amd_iommu *iommu)
  135.58 +static void __init register_iommu_event_log_in_mmio_space(struct amd_iommu *iommu)
  135.59  {
  135.60      u64 addr_64, addr_lo, addr_hi;
  135.61      u32 power_of2_entries;
  135.62 @@ -266,12 +276,13 @@ static int amd_iommu_read_event_log(stru
  135.63      return -EFAULT;
  135.64  }
  135.65  
  135.66 -static void amd_iommu_msi_data_init(struct amd_iommu *iommu, int vector)
  135.67 +static void amd_iommu_msi_data_init(struct amd_iommu *iommu)
  135.68  {
  135.69      u32 msi_data;
  135.70      u8 bus = (iommu->bdf >> 8) & 0xff;
  135.71      u8 dev = PCI_SLOT(iommu->bdf & 0xff);
  135.72      u8 func = PCI_FUNC(iommu->bdf & 0xff);
  135.73 +    int vector = iommu->vector;
  135.74  
  135.75      msi_data = MSI_DATA_TRIGGER_EDGE |
  135.76          MSI_DATA_LEVEL_ASSERT |
  135.77 @@ -434,7 +445,6 @@ static void amd_iommu_page_fault(int vec
  135.78  static int set_iommu_interrupt_handler(struct amd_iommu *iommu)
  135.79  {
  135.80      int vector, ret;
  135.81 -    unsigned long flags;
  135.82  
  135.83      vector = assign_irq_vector(AUTO_ASSIGN);
  135.84      vector_to_iommu[vector] = iommu;
  135.85 @@ -450,21 +460,13 @@ static int set_iommu_interrupt_handler(s
  135.86      }
  135.87  
  135.88      irq_desc[vector].handler = &iommu_msi_type;
  135.89 -    ret = request_irq(vector, amd_iommu_page_fault, 0, "dmar", iommu);
  135.90 +    ret = request_irq(vector, amd_iommu_page_fault, 0, "amd_iommu", iommu);
  135.91      if ( ret )
  135.92      {
  135.93          amd_iov_error("can't request irq\n");
  135.94          return 0;
  135.95      }
  135.96  
  135.97 -    spin_lock_irqsave(&iommu->lock, flags);
  135.98 -
  135.99 -    amd_iommu_msi_data_init (iommu, vector);
 135.100 -    amd_iommu_msi_addr_init(iommu, cpu_physical_id(first_cpu(cpu_online_map)));
 135.101 -    amd_iommu_msi_enable(iommu, IOMMU_CONTROL_ENABLED);
 135.102 -
 135.103 -    spin_unlock_irqrestore(&iommu->lock, flags);
 135.104 -
 135.105      return vector;
 135.106  }
 135.107  
 135.108 @@ -472,16 +474,196 @@ void __init enable_iommu(struct amd_iomm
 135.109  {
 135.110      unsigned long flags;
 135.111  
 135.112 -    set_iommu_interrupt_handler(iommu);
 135.113 -
 135.114      spin_lock_irqsave(&iommu->lock, flags);
 135.115  
 135.116 +    if ( iommu->enabled )
 135.117 +    {
 135.118 +        spin_unlock_irqrestore(&iommu->lock, flags); 
 135.119 +        return;
 135.120 +    }
 135.121 +
 135.122 +    iommu->dev_table.alloc_size = device_table.alloc_size;
 135.123 +    iommu->dev_table.entries = device_table.entries;
 135.124 +    iommu->dev_table.buffer = device_table.buffer;
 135.125 +
 135.126 +    register_iommu_dev_table_in_mmio_space(iommu);
 135.127 +    register_iommu_cmd_buffer_in_mmio_space(iommu);
 135.128 +    register_iommu_event_log_in_mmio_space(iommu);
 135.129      register_iommu_exclusion_range(iommu);
 135.130 +
 135.131 +    amd_iommu_msi_data_init (iommu);
 135.132 +    amd_iommu_msi_addr_init(iommu, cpu_physical_id(first_cpu(cpu_online_map)));
 135.133 +    amd_iommu_msi_enable(iommu, IOMMU_CONTROL_ENABLED);
 135.134 +
 135.135      set_iommu_command_buffer_control(iommu, IOMMU_CONTROL_ENABLED);
 135.136      set_iommu_event_log_control(iommu, IOMMU_CONTROL_ENABLED);
 135.137      set_iommu_translation_control(iommu, IOMMU_CONTROL_ENABLED);
 135.138  
 135.139 +    printk("AMD_IOV: IOMMU %d Enabled.\n", nr_amd_iommus );
 135.140 +    nr_amd_iommus++;
 135.141 +
 135.142 +    iommu->enabled = 1;
 135.143      spin_unlock_irqrestore(&iommu->lock, flags);
 135.144  
 135.145 -    printk("AMD_IOV: IOMMU %d Enabled.\n", nr_amd_iommus);
 135.146 +}
 135.147 +
 135.148 +static void __init deallocate_iommu_table_struct(
 135.149 +    struct table_struct *table)
 135.150 +{
 135.151 +    if ( table->buffer )
 135.152 +    {
 135.153 +        free_xenheap_pages(table->buffer,
 135.154 +            get_order_from_bytes(table->alloc_size));
 135.155 +        table->buffer = NULL;
 135.156 +    }
 135.157 +}
 135.158 +
 135.159 +static void __init deallocate_iommu_tables(struct amd_iommu *iommu)
 135.160 +{
 135.161 +    deallocate_iommu_table_struct(&iommu->cmd_buffer);
 135.162 +    deallocate_iommu_table_struct(&iommu->event_log);
 135.163 +}
 135.164 +
 135.165 +static int __init allocate_iommu_table_struct(struct table_struct *table,
 135.166 +                                              const char *name)
 135.167 +{
 135.168 +    table->buffer = (void *) alloc_xenheap_pages(
 135.169 +        get_order_from_bytes(table->alloc_size));
 135.170 +
 135.171 +    if ( !table->buffer )
 135.172 +    {
 135.173 +        amd_iov_error("Error allocating %s\n", name);
 135.174 +        return -ENOMEM;
 135.175 +    }
 135.176 +
 135.177 +    memset(table->buffer, 0, table->alloc_size);
 135.178 +    return 0;
 135.179 +}
 135.180 +
 135.181 +static int __init allocate_iommu_tables(struct amd_iommu *iommu)
 135.182 +{
 135.183 +    /* allocate 'command buffer' in power of 2 increments of 4K */
 135.184 +    iommu->cmd_buffer_tail = 0;
 135.185 +    iommu->cmd_buffer.alloc_size = PAGE_SIZE << get_order_from_bytes(
 135.186 +        PAGE_ALIGN(amd_iommu_cmd_buffer_entries * IOMMU_CMD_BUFFER_ENTRY_SIZE));
 135.187 +    iommu->cmd_buffer.entries =
 135.188 +        iommu->cmd_buffer.alloc_size / IOMMU_CMD_BUFFER_ENTRY_SIZE;
 135.189 +
 135.190 +    if ( allocate_iommu_table_struct(&iommu->cmd_buffer, "Command Buffer") != 0 )
 135.191 +        goto error_out;
 135.192 +
 135.193 +    /* allocate 'event log' in power of 2 increments of 4K */
 135.194 +    iommu->event_log_head = 0;
 135.195 +    iommu->event_log.alloc_size = PAGE_SIZE << get_order_from_bytes(
 135.196 +        PAGE_ALIGN(amd_iommu_event_log_entries * IOMMU_EVENT_LOG_ENTRY_SIZE));
 135.197 +    iommu->event_log.entries =
 135.198 +        iommu->event_log.alloc_size / IOMMU_EVENT_LOG_ENTRY_SIZE;
 135.199 +
 135.200 +    if ( allocate_iommu_table_struct(&iommu->event_log, "Event Log") != 0 )
 135.201 +        goto error_out;
 135.202 +
 135.203 +    return 0;
 135.204 +
 135.205 + error_out:
 135.206 +    deallocate_iommu_tables(iommu);
 135.207 +    return -ENOMEM;
 135.208  }
 135.209 +
 135.210 +int __init amd_iommu_init_one(struct amd_iommu *iommu)
 135.211 +{
 135.212 +
 135.213 +    if ( allocate_iommu_tables(iommu) != 0 )
 135.214 +        goto error_out;
 135.215 +
 135.216 +    if ( map_iommu_mmio_region(iommu) != 0 )
 135.217 +        goto error_out;
 135.218 +
 135.219 +    if ( set_iommu_interrupt_handler(iommu) == 0 )
 135.220 +        goto error_out;
 135.221 +
 135.222 +    enable_iommu(iommu);
 135.223 +    return 0;
 135.224 +
 135.225 +error_out:
 135.226 +    return -ENODEV;
 135.227 +}
 135.228 +
 135.229 +void __init amd_iommu_init_cleanup(void)
 135.230 +{
 135.231 +    struct amd_iommu *iommu, *next;
 135.232 +
 135.233 +    list_for_each_entry_safe ( iommu, next, &amd_iommu_head, list )
 135.234 +    {
 135.235 +        list_del(&iommu->list);
 135.236 +        if ( iommu->enabled )
 135.237 +        {
 135.238 +            deallocate_iommu_tables(iommu);
 135.239 +            unmap_iommu_mmio_region(iommu);
 135.240 +        }
 135.241 +        xfree(iommu);
 135.242 +    }
 135.243 +}
 135.244 +
 135.245 +static int __init init_ivrs_mapping(void)
 135.246 +{
 135.247 +    int bdf;
 135.248 +
 135.249 +    BUG_ON( !ivrs_bdf_entries );
 135.250 +
 135.251 +    ivrs_mappings = xmalloc_array( struct ivrs_mappings, ivrs_bdf_entries);
 135.252 +    if ( ivrs_mappings == NULL )
 135.253 +    {
 135.254 +        amd_iov_error("Error allocating IVRS Mappings table\n");
 135.255 +        return -ENOMEM;
 135.256 +    }
 135.257 +    memset(ivrs_mappings, 0, ivrs_bdf_entries * sizeof(struct ivrs_mappings));
 135.258 +
 135.259 +    /* assign default values for device entries */
 135.260 +    for ( bdf = 0; bdf < ivrs_bdf_entries; bdf++ )
 135.261 +    {
 135.262 +        ivrs_mappings[bdf].dte_requestor_id = bdf;
 135.263 +        ivrs_mappings[bdf].dte_sys_mgt_enable =
 135.264 +            IOMMU_DEV_TABLE_SYS_MGT_MSG_FORWARDED;
 135.265 +        ivrs_mappings[bdf].dte_allow_exclusion = IOMMU_CONTROL_DISABLED;
 135.266 +        ivrs_mappings[bdf].unity_map_enable = IOMMU_CONTROL_DISABLED;
 135.267 +        ivrs_mappings[bdf].iommu = NULL;
 135.268 +    }
 135.269 +    return 0;
 135.270 +}
 135.271 +
 135.272 +static int __init amd_iommu_setup_device_table(void)
 135.273 +{
 135.274 +    /* allocate 'device table' on a 4K boundary */
 135.275 +    device_table.alloc_size = PAGE_SIZE << get_order_from_bytes(
 135.276 +        PAGE_ALIGN(ivrs_bdf_entries * IOMMU_DEV_TABLE_ENTRY_SIZE));
 135.277 +    device_table.entries = device_table.alloc_size / IOMMU_DEV_TABLE_ENTRY_SIZE;
 135.278 +
 135.279 +    return ( allocate_iommu_table_struct(&device_table, "Device Table") );
 135.280 +}
 135.281 +
 135.282 +int __init amd_iommu_setup_shared_tables(void)
 135.283 +{
 135.284 +    BUG_ON( !ivrs_bdf_entries );
 135.285 +
 135.286 +    if (init_ivrs_mapping() != 0 )
 135.287 +        goto error_out;
 135.288 +
 135.289 +    if ( amd_iommu_setup_device_table() != 0 )
 135.290 +        goto error_out;
 135.291 +
 135.292 +    if ( amd_iommu_setup_intremap_table() != 0 )
 135.293 +        goto error_out;
 135.294 +
 135.295 +    return 0;
 135.296 +
 135.297 +error_out:
 135.298 +    deallocate_intremap_table();
 135.299 +    deallocate_iommu_table_struct(&device_table);
 135.300 +
 135.301 +    if ( ivrs_mappings )
 135.302 +    {
 135.303 +        xfree(ivrs_mappings);
 135.304 +        ivrs_mappings = NULL;
 135.305 +    }
 135.306 +    return -ENOMEM;
 135.307 +}
   136.1 --- a/xen/drivers/passthrough/amd/iommu_intr.c	Thu Aug 07 11:47:34 2008 +0900
   136.2 +++ b/xen/drivers/passthrough/amd/iommu_intr.c	Thu Aug 07 11:57:34 2008 +0900
   136.3 @@ -107,7 +107,7 @@ static void update_intremap_entry_from_i
   136.4      return;
   136.5  }
   136.6  
   136.7 -int amd_iommu_setup_intremap_table(void)
   136.8 +int __init amd_iommu_setup_intremap_table(void)
   136.9  {
  136.10      unsigned long flags;
  136.11  
  136.12 @@ -203,3 +203,18 @@ void amd_iommu_msi_msg_update_ire(
  136.13  
  136.14      update_intremap_entry_from_msi_msg(iommu, pdev, msg);
  136.15  }
  136.16 +
  136.17 +int __init deallocate_intremap_table(void)
  136.18 +{
  136.19 +    unsigned long flags;
  136.20 +
  136.21 +    spin_lock_irqsave(&int_remap_table_lock, flags);
  136.22 +    if ( int_remap_table )
  136.23 +    {
  136.24 +        free_xenheap_pages(int_remap_table, 1);
  136.25 +        int_remap_table = NULL;
  136.26 +    }
  136.27 +    spin_unlock_irqrestore(&int_remap_table_lock, flags);
  136.28 +
  136.29 +    return 0;
  136.30 +}
   137.1 --- a/xen/drivers/passthrough/amd/iommu_map.c	Thu Aug 07 11:47:34 2008 +0900
   137.2 +++ b/xen/drivers/passthrough/amd/iommu_map.c	Thu Aug 07 11:57:34 2008 +0900
   137.3 @@ -23,7 +23,7 @@
   137.4  #include <asm/amd-iommu.h>
   137.5  #include <asm/hvm/svm/amd-iommu-proto.h>
   137.6  
   137.7 -extern long amd_iommu_poll_comp_wait;
   137.8 +long amd_iommu_poll_comp_wait = COMPLETION_WAIT_DEFAULT_POLLING_COUNT;
   137.9  
  137.10  static int queue_iommu_command(struct amd_iommu *iommu, u32 cmd[])
  137.11  {
   138.1 --- a/xen/drivers/passthrough/amd/pci_amd_iommu.c	Thu Aug 07 11:47:34 2008 +0900
   138.2 +++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c	Thu Aug 07 11:57:34 2008 +0900
   138.3 @@ -23,17 +23,10 @@
   138.4  #include <xen/pci_regs.h>
   138.5  #include <asm/amd-iommu.h>
   138.6  #include <asm/hvm/svm/amd-iommu-proto.h>
   138.7 -#include <asm/hvm/svm/amd-iommu-acpi.h>
   138.8  #include <asm/mm.h>
   138.9  
  138.10 -struct list_head amd_iommu_head;
  138.11 -long amd_iommu_poll_comp_wait = COMPLETION_WAIT_DEFAULT_POLLING_COUNT;
  138.12 -static long amd_iommu_cmd_buffer_entries = IOMMU_CMD_BUFFER_DEFAULT_ENTRIES;
  138.13 -static long amd_iommu_event_log_entries = IOMMU_EVENT_LOG_DEFAULT_ENTRIES;
  138.14 -int nr_amd_iommus;
  138.15 -
  138.16 -unsigned short ivrs_bdf_entries;
  138.17 -struct ivrs_mappings *ivrs_mappings;
  138.18 +extern unsigned short ivrs_bdf_entries;
  138.19 +extern struct ivrs_mappings *ivrs_mappings;
  138.20  extern void *int_remap_table;
  138.21  
  138.22  static void deallocate_domain_page_tables(struct hvm_iommu *hd)
  138.23 @@ -47,209 +40,39 @@ static void deallocate_domain_resources(
  138.24      deallocate_domain_page_tables(hd);
  138.25  }
  138.26  
  138.27 -static void __init init_cleanup(void)
  138.28 +int __init amd_iommu_init(void)
  138.29  {
  138.30      struct amd_iommu *iommu;
  138.31  
  138.32 -    for_each_amd_iommu ( iommu )
  138.33 -        unmap_iommu_mmio_region(iommu);
  138.34 -}
  138.35 -
  138.36 -static void __init deallocate_iommu_table_struct(
  138.37 -    struct table_struct *table)
  138.38 -{
  138.39 -    if ( table->buffer )
  138.40 -    {
  138.41 -        free_xenheap_pages(table->buffer,
  138.42 -                           get_order_from_bytes(table->alloc_size));
  138.43 -        table->buffer = NULL;
  138.44 -    }
  138.45 -}
  138.46 -
  138.47 -static void __init deallocate_iommu_resources(struct amd_iommu *iommu)
  138.48 -{
  138.49 -    deallocate_iommu_table_struct(&iommu->dev_table);
  138.50 -    deallocate_iommu_table_struct(&iommu->cmd_buffer);
  138.51 -    deallocate_iommu_table_struct(&iommu->event_log);
  138.52 -}
  138.53 +    BUG_ON( !iommu_found() );
  138.54  
  138.55 -static int __init allocate_iommu_table_struct(struct table_struct *table,
  138.56 -                                              const char *name)
  138.57 -{
  138.58 -    table->buffer = (void *) alloc_xenheap_pages(
  138.59 -        get_order_from_bytes(table->alloc_size));
  138.60 -
  138.61 -    if ( !table->buffer )
  138.62 -    {
  138.63 -        amd_iov_error("Error allocating %s\n", name);
  138.64 -        return -ENOMEM;
  138.65 -    }
  138.66 -
  138.67 -    memset(table->buffer, 0, table->alloc_size);
  138.68 +    ivrs_bdf_entries = amd_iommu_get_ivrs_dev_entries();
  138.69  
  138.70 -    return 0;
  138.71 -}
  138.72 -
  138.73 -static int __init allocate_iommu_resources(struct amd_iommu *iommu)
  138.74 -{
  138.75 -    /* allocate 'device table' on a 4K boundary */
  138.76 -    iommu->dev_table.alloc_size =
  138.77 -        PAGE_ALIGN(((iommu->last_downstream_bus + 1) *
  138.78 -                    IOMMU_DEV_TABLE_ENTRIES_PER_BUS) *
  138.79 -                   IOMMU_DEV_TABLE_ENTRY_SIZE);
  138.80 -    iommu->dev_table.entries =
  138.81 -        iommu->dev_table.alloc_size / IOMMU_DEV_TABLE_ENTRY_SIZE;
  138.82 -
  138.83 -    if ( allocate_iommu_table_struct(&iommu->dev_table,
  138.84 -                                     "Device Table") != 0 )
  138.85 +    if ( !ivrs_bdf_entries )
  138.86          goto error_out;
  138.87  
  138.88 -    /* allocate 'command buffer' in power of 2 increments of 4K */
  138.89 -    iommu->cmd_buffer_tail = 0;
  138.90 -    iommu->cmd_buffer.alloc_size =
  138.91 -        PAGE_SIZE << get_order_from_bytes(
  138.92 -            PAGE_ALIGN(amd_iommu_cmd_buffer_entries *
  138.93 -                       IOMMU_CMD_BUFFER_ENTRY_SIZE));
  138.94 -
  138.95 -    iommu->cmd_buffer.entries =
  138.96 -        iommu->cmd_buffer.alloc_size / IOMMU_CMD_BUFFER_ENTRY_SIZE;
  138.97 -
  138.98 -    if ( allocate_iommu_table_struct(&iommu->cmd_buffer,
  138.99 -                                     "Command Buffer") != 0 )
 138.100 +    if ( amd_iommu_setup_shared_tables() != 0 )
 138.101          goto error_out;
 138.102  
 138.103 -    /* allocate 'event log' in power of 2 increments of 4K */
 138.104 -    iommu->event_log_head = 0;
 138.105 -    iommu->event_log.alloc_size =
 138.106 -        PAGE_SIZE << get_order_from_bytes(
 138.107 -            PAGE_ALIGN(amd_iommu_event_log_entries *
 138.108 -                        IOMMU_EVENT_LOG_ENTRY_SIZE));
 138.109 +    if ( amd_iommu_update_ivrs_mapping_acpi() != 0 )
 138.110 +        goto error_out;
 138.111  
 138.112 -    iommu->event_log.entries =
 138.113 -        iommu->event_log.alloc_size / IOMMU_EVENT_LOG_ENTRY_SIZE;
 138.114 -
 138.115 -    if ( allocate_iommu_table_struct(&iommu->event_log,
 138.116 -                                     "Event Log") != 0 )
 138.117 -        goto error_out;
 138.118 +    for_each_amd_iommu ( iommu )
 138.119 +        if ( amd_iommu_init_one(iommu) != 0 )
 138.120 +            goto error_out;
 138.121  
 138.122      return 0;
 138.123  
 138.124 - error_out:
 138.125 -    deallocate_iommu_resources(iommu);
 138.126 -    return -ENOMEM;
 138.127 -}
 138.128 -
 138.129 -int iommu_detect_callback(u8 bus, u8 dev, u8 func, u8 cap_ptr)
 138.130 -{
 138.131 -    struct amd_iommu *iommu;
 138.132 -
 138.133 -    iommu = (struct amd_iommu *) xmalloc(struct amd_iommu);
 138.134 -    if ( !iommu )
 138.135 -    {
 138.136 -        amd_iov_error("Error allocating amd_iommu\n");
 138.137 -        return -ENOMEM;
 138.138 -    }
 138.139 -    memset(iommu, 0, sizeof(struct amd_iommu));
 138.140 -    spin_lock_init(&iommu->lock);
 138.141 -
 138.142 -    /* get capability and topology information */
 138.143 -    if ( get_iommu_capabilities(bus, dev, func, cap_ptr, iommu) != 0 )
 138.144 -        goto error_out;
 138.145 -    if ( get_iommu_last_downstream_bus(iommu) != 0 )
 138.146 -        goto error_out;
 138.147 -
 138.148 -    list_add_tail(&iommu->list, &amd_iommu_head);
 138.149 -
 138.150 -    /* allocate resources for this IOMMU */
 138.151 -    if ( allocate_iommu_resources(iommu) != 0 )
 138.152 -        goto error_out;
 138.153 -
 138.154 -    return 0;
 138.155 -
 138.156 - error_out:
 138.157 -    xfree(iommu);
 138.158 -    return -ENODEV;
 138.159 -}
 138.160 -
 138.161 -static int __init amd_iommu_init(void)
 138.162 -{
 138.163 -    struct amd_iommu *iommu;
 138.164 -    unsigned long flags;
 138.165 -    u16 bdf;
 138.166 -
 138.167 -    for_each_amd_iommu ( iommu )
 138.168 -    {
 138.169 -        spin_lock_irqsave(&iommu->lock, flags);
 138.170 -
 138.171 -        /* assign default IOMMU values */
 138.172 -        iommu->coherent = IOMMU_CONTROL_ENABLED;
 138.173 -        iommu->isochronous = IOMMU_CONTROL_ENABLED;
 138.174 -        iommu->res_pass_pw = IOMMU_CONTROL_ENABLED;
 138.175 -        iommu->pass_pw = IOMMU_CONTROL_ENABLED;
 138.176 -        iommu->ht_tunnel_enable = iommu->ht_tunnel_support ?
 138.177 -            IOMMU_CONTROL_ENABLED : IOMMU_CONTROL_DISABLED;
 138.178 -        iommu->exclusion_enable = IOMMU_CONTROL_DISABLED;
 138.179 -        iommu->exclusion_allow_all = IOMMU_CONTROL_DISABLED;
 138.180 -
 138.181 -        /* register IOMMU data strucures in MMIO space */
 138.182 -        if ( map_iommu_mmio_region(iommu) != 0 )
 138.183 -            goto error_out;
 138.184 -        register_iommu_dev_table_in_mmio_space(iommu);
 138.185 -        register_iommu_cmd_buffer_in_mmio_space(iommu);
 138.186 -        register_iommu_event_log_in_mmio_space(iommu);
 138.187 -
 138.188 -        spin_unlock_irqrestore(&iommu->lock, flags);
 138.189 -    }
 138.190 -
 138.191 -    /* assign default values for device entries */
 138.192 -    for ( bdf = 0; bdf < ivrs_bdf_entries; bdf++ )
 138.193 -    {
 138.194 -        ivrs_mappings[bdf].dte_requestor_id = bdf;
 138.195 -        ivrs_mappings[bdf].dte_sys_mgt_enable =
 138.196 -            IOMMU_DEV_TABLE_SYS_MGT_MSG_FORWARDED;
 138.197 -        ivrs_mappings[bdf].dte_allow_exclusion =
 138.198 -            IOMMU_CONTROL_DISABLED;
 138.199 -        ivrs_mappings[bdf].unity_map_enable =
 138.200 -            IOMMU_CONTROL_DISABLED;
 138.201 -    }
 138.202 -
 138.203 -    if ( acpi_table_parse(AMD_IOMMU_ACPI_IVRS_SIG, parse_ivrs_table) != 0 )
 138.204 -        amd_iov_error("Did not find IVRS table!\n");
 138.205 -
 138.206 -    for_each_amd_iommu ( iommu )
 138.207 -    {
 138.208 -        /* enable IOMMU translation services */
 138.209 -        enable_iommu(iommu);
 138.210 -        nr_amd_iommus++;
 138.211 -    }
 138.212 -
 138.213 -    return 0;
 138.214 -
 138.215 - error_out:
 138.216 -    init_cleanup();
 138.217 +error_out:
 138.218 +    amd_iommu_init_cleanup();
 138.219      return -ENODEV;
 138.220  }
 138.221  
 138.222  struct amd_iommu *find_iommu_for_device(int bus, int devfn)
 138.223  {
 138.224 -    struct amd_iommu *iommu;
 138.225 -
 138.226 -    for_each_amd_iommu ( iommu )
 138.227 -    {
 138.228 -        if ( bus == iommu->root_bus )
 138.229 -        {
 138.230 -            if ( (devfn >= iommu->first_devfn) &&
 138.231 -                 (devfn <= iommu->last_devfn) )
 138.232 -                return iommu;
 138.233 -        }
 138.234 -        else if ( bus <= iommu->last_downstream_bus )
 138.235 -        {
 138.236 -            if ( iommu->downstream_bus_present[bus] )
 138.237 -                return iommu;
 138.238 -        }
 138.239 -    }
 138.240 -
 138.241 -    return NULL;
 138.242 +    u16 bdf = (bus << 8) | devfn;
 138.243 +    BUG_ON ( bdf >= ivrs_bdf_entries );
 138.244 +    return ivrs_mappings[bdf].iommu;
 138.245  }
 138.246  
 138.247  static void amd_iommu_setup_domain_device(
 138.248 @@ -335,70 +158,26 @@ static void amd_iommu_setup_dom0_devices
 138.249  
 138.250  int amd_iov_detect(void)
 138.251  {
 138.252 -    int last_bus;
 138.253 -    struct amd_iommu *iommu, *next;
 138.254 -
 138.255      INIT_LIST_HEAD(&amd_iommu_head);
 138.256  
 138.257 -    if ( scan_for_iommu(iommu_detect_callback) != 0 )
 138.258 +    if ( amd_iommu_detect_acpi() != 0 )
 138.259      {
 138.260          amd_iov_error("Error detection\n");
 138.261 -        goto error_out;
 138.262 +        return -ENODEV;
 138.263      }
 138.264  
 138.265      if ( !iommu_found() )
 138.266      {
 138.267          printk("AMD_IOV: IOMMU not found!\n");
 138.268 -        goto error_out;
 138.269 -    }
 138.270 -
 138.271 -    /* allocate 'ivrs mappings' table */
 138.272 -    /* note: the table has entries to accomodate all IOMMUs */
 138.273 -    last_bus = 0;
 138.274 -    for_each_amd_iommu ( iommu )
 138.275 -        if ( iommu->last_downstream_bus > last_bus )
 138.276 -            last_bus = iommu->last_downstream_bus;
 138.277 -
 138.278 -    ivrs_bdf_entries = (last_bus + 1) *
 138.279 -        IOMMU_DEV_TABLE_ENTRIES_PER_BUS;
 138.280 -    ivrs_mappings = xmalloc_array( struct ivrs_mappings, ivrs_bdf_entries);
 138.281 -    if ( ivrs_mappings == NULL )
 138.282 -    {
 138.283 -        amd_iov_error("Error allocating IVRS DevMappings table\n");
 138.284 -        goto error_out;
 138.285 -    }
 138.286 -    memset(ivrs_mappings, 0,
 138.287 -           ivrs_bdf_entries * sizeof(struct ivrs_mappings));
 138.288 -
 138.289 -    if ( amd_iommu_setup_intremap_table() != 0 )
 138.290 -    {
 138.291 -        amd_iov_error("Error allocating interrupt remapping table\n");
 138.292 -        goto error_out;
 138.293 +        return -ENODEV;
 138.294      }
 138.295  
 138.296      if ( amd_iommu_init() != 0 )
 138.297      {
 138.298          amd_iov_error("Error initialization\n");
 138.299 -        goto error_out;
 138.300 +        return -ENODEV;
 138.301      }
 138.302 -
 138.303      return 0;
 138.304 -
 138.305 - error_out:
 138.306 -    list_for_each_entry_safe ( iommu, next, &amd_iommu_head, list )
 138.307 -    {
 138.308 -        list_del(&iommu->list);
 138.309 -        deallocate_iommu_resources(iommu);
 138.310 -        xfree(iommu);
 138.311 -    }
 138.312 -
 138.313 -    if ( ivrs_mappings )
 138.314 -    {
 138.315 -        xfree(ivrs_mappings);
 138.316 -        ivrs_mappings = NULL;
 138.317 -    }
 138.318 -
 138.319 -    return -ENODEV;
 138.320  }
 138.321  
 138.322  static int allocate_domain_resources(struct hvm_iommu *hd)
   139.1 --- a/xen/drivers/passthrough/iommu.c	Thu Aug 07 11:47:34 2008 +0900
   139.2 +++ b/xen/drivers/passthrough/iommu.c	Thu Aug 07 11:57:34 2008 +0900
   139.3 @@ -20,15 +20,48 @@
   139.4  
   139.5  extern struct iommu_ops intel_iommu_ops;
   139.6  extern struct iommu_ops amd_iommu_ops;
   139.7 +static void parse_iommu_param(char *s);
   139.8  static int iommu_populate_page_table(struct domain *d);
   139.9  int intel_vtd_setup(void);
  139.10  int amd_iov_detect(void);
  139.11  
  139.12 +/*
  139.13 + * The 'iommu' parameter enables the IOMMU.  Optional comma separated
  139.14 + * value may contain:
  139.15 + *
  139.16 + *   off|no|false|disable       Disable IOMMU (default)
  139.17 + *   pv                         Enable IOMMU for PV domains
  139.18 + *   no-pv                      Disable IOMMU for PV domains (default)
  139.19 + *   force|required             Don't boot unless IOMMU is enabled
  139.20 + */
  139.21 +custom_param("iommu", parse_iommu_param);
  139.22  int iommu_enabled = 0;
  139.23 -boolean_param("iommu", iommu_enabled);
  139.24 +int iommu_pv_enabled = 0;
  139.25 +int force_iommu = 0;
  139.26 +
  139.27 +static void __init parse_iommu_param(char *s)
  139.28 +{
  139.29 +    char *ss;
  139.30 +    iommu_enabled = 1;
  139.31  
  139.32 -int iommu_pv_enabled = 0;
  139.33 -boolean_param("iommu_pv", iommu_pv_enabled);
  139.34 +    do {
  139.35 +        ss = strchr(s, ',');
  139.36 +        if ( ss )
  139.37 +            *ss = '\0';
  139.38 +
  139.39 +        if ( !strcmp(s, "off") || !strcmp(s, "no") || !strcmp(s, "false") ||
  139.40 +             !strcmp(s, "0") || !strcmp(s, "disable") )
  139.41 +            iommu_enabled = 0;
  139.42 +        else if ( !strcmp(s, "pv") )
  139.43 +            iommu_pv_enabled = 1;
  139.44 +        else if ( !strcmp(s, "no-pv") )
  139.45 +            iommu_pv_enabled = 0;
  139.46 +        else if ( !strcmp(s, "force") || !strcmp(s, "required") )
  139.47 +            force_iommu = 1;
  139.48 +
  139.49 +        s = ss + 1;
  139.50 +    } while ( ss );
  139.51 +}
  139.52  
  139.53  int iommu_domain_init(struct domain *domain)
  139.54  {
  139.55 @@ -126,14 +159,12 @@ static int iommu_populate_page_table(str
  139.56      return 0;
  139.57  }
  139.58  
  139.59 +
  139.60  void iommu_domain_destroy(struct domain *d)
  139.61  {
  139.62 -    struct hvm_irq_dpci *hvm_irq_dpci = domain_get_irq_dpci(d);
  139.63 -    uint32_t i;
  139.64      struct hvm_iommu *hd  = domain_hvm_iommu(d);
  139.65 -    struct list_head *ioport_list, *digl_list, *tmp;
  139.66 +    struct list_head *ioport_list, *tmp;
  139.67      struct g2m_ioport *ioport;
  139.68 -    struct dev_intx_gsi_link *digl;
  139.69  
  139.70      if ( !iommu_enabled || !hd->platform_ops )
  139.71          return;
  139.72 @@ -148,30 +179,6 @@ void iommu_domain_destroy(struct domain 
  139.73          return;
  139.74      }
  139.75  
  139.76 -    if ( hvm_irq_dpci != NULL )
  139.77 -    {
  139.78 -        for ( i = 0; i < NR_IRQS; i++ )
  139.79 -        {
  139.80 -            if ( !(hvm_irq_dpci->mirq[i].flags & HVM_IRQ_DPCI_VALID) )
  139.81 -                continue;
  139.82 -
  139.83 -            pirq_guest_unbind(d, i);
  139.84 -            kill_timer(&hvm_irq_dpci->hvm_timer[irq_to_vector(i)]);
  139.85 -
  139.86 -            list_for_each_safe ( digl_list, tmp,
  139.87 -                                 &hvm_irq_dpci->mirq[i].digl_list )
  139.88 -            {
  139.89 -                digl = list_entry(digl_list,
  139.90 -                                  struct dev_intx_gsi_link, list);
  139.91 -                list_del(&digl->list);
  139.92 -                xfree(digl);
  139.93 -            }
  139.94 -        }
  139.95 -
  139.96 -        d->arch.hvm_domain.irq.dpci = NULL;
  139.97 -        xfree(hvm_irq_dpci);
  139.98 -    }
  139.99 -
 139.100      if ( hd )
 139.101      {
 139.102          list_for_each_safe ( ioport_list, tmp, &hd->g2m_ioport_list )
 139.103 @@ -241,6 +248,9 @@ static int iommu_setup(void)
 139.104      iommu_enabled = (rc == 0);
 139.105  
 139.106   out:
 139.107 +    if ( force_iommu && !iommu_enabled )
 139.108 +        panic("IOMMU setup failed, crash Xen for security purpose!\n");
 139.109 +
 139.110      if ( !iommu_enabled )
 139.111          iommu_pv_enabled = 0;
 139.112      printk("I/O virtualisation %sabled\n", iommu_enabled ? "en" : "dis");
   140.1 --- a/xen/drivers/passthrough/pci.c	Thu Aug 07 11:47:34 2008 +0900
   140.2 +++ b/xen/drivers/passthrough/pci.c	Thu Aug 07 11:57:34 2008 +0900
   140.3 @@ -34,11 +34,11 @@ struct pci_dev *alloc_pdev(u8 bus, u8 de
   140.4  
   140.5      list_for_each_entry ( pdev, &alldevs_list, alldevs_list )
   140.6          if ( pdev->bus == bus && pdev->devfn == devfn )
   140.7 -	    return pdev;
   140.8 +            return pdev;
   140.9  
  140.10      pdev = xmalloc(struct pci_dev);
  140.11      if ( !pdev )
  140.12 -	return NULL;
  140.13 +        return NULL;
  140.14  
  140.15      *((u8*) &pdev->bus) = bus;
  140.16      *((u8*) &pdev->devfn) = devfn;
  140.17 @@ -63,12 +63,12 @@ struct pci_dev *pci_lock_pdev(int bus, i
  140.18      read_lock(&pcidevs_lock);
  140.19      list_for_each_entry ( pdev, &alldevs_list, alldevs_list )
  140.20          if ( (pdev->bus == bus || bus == -1) &&
  140.21 -	     (pdev->devfn == devfn || devfn == -1) )
  140.22 -	{
  140.23 -	    spin_lock(&pdev->lock);
  140.24 -	    read_unlock(&pcidevs_lock);
  140.25 -	    return pdev;
  140.26 -	}
  140.27 +             (pdev->devfn == devfn || devfn == -1) )
  140.28 +    {
  140.29 +        spin_lock(&pdev->lock);
  140.30 +        read_unlock(&pcidevs_lock);
  140.31 +        return pdev;
  140.32 +    }
  140.33      read_unlock(&pcidevs_lock);
  140.34  
  140.35      return NULL;
  140.36 @@ -81,15 +81,15 @@ struct pci_dev *pci_lock_domain_pdev(str
  140.37      read_lock(&pcidevs_lock);
  140.38      list_for_each_entry ( pdev, &d->arch.pdev_list, domain_list )
  140.39      {
  140.40 -	spin_lock(&pdev->lock);
  140.41 +        spin_lock(&pdev->lock);
  140.42          if ( (pdev->bus == bus || bus == -1) &&
  140.43 -	     (pdev->devfn == devfn || devfn == -1) &&
  140.44 -	     (pdev->domain == d) )
  140.45 -	{
  140.46 -	    read_unlock(&pcidevs_lock);
  140.47 -	    return pdev;
  140.48 -	}
  140.49 -	spin_unlock(&pdev->lock);
  140.50 +             (pdev->devfn == devfn || devfn == -1) &&
  140.51 +             (pdev->domain == d) )
  140.52 +        {
  140.53 +            read_unlock(&pcidevs_lock);
  140.54 +            return pdev;
  140.55 +        }
  140.56 +        spin_unlock(&pdev->lock);
  140.57      }
  140.58      read_unlock(&pcidevs_lock);
  140.59  
  140.60 @@ -104,19 +104,24 @@ int pci_add_device(u8 bus, u8 devfn)
  140.61      write_lock(&pcidevs_lock);
  140.62      pdev = alloc_pdev(bus, devfn);
  140.63      if ( !pdev )
  140.64 -	goto out;
  140.65 +        goto out;
  140.66  
  140.67      ret = 0;
  140.68      spin_lock(&pdev->lock);
  140.69      if ( !pdev->domain )
  140.70      {
  140.71 -	pdev->domain = dom0;
  140.72 -	list_add(&pdev->domain_list, &dom0->arch.pdev_list);
  140.73 -	ret = iommu_add_device(pdev);
  140.74 +        pdev->domain = dom0;
  140.75 +        ret = iommu_add_device(pdev);
  140.76 +        if ( ret )
  140.77 +        {
  140.78 +            spin_unlock(&pdev->lock);
  140.79 +            goto out;
  140.80 +        }
  140.81 +        list_add(&pdev->domain_list, &dom0->arch.pdev_list);
  140.82      }
  140.83      spin_unlock(&pdev->lock);
  140.84      printk(XENLOG_DEBUG "PCI add device %02x:%02x.%x\n", bus,
  140.85 -	   PCI_SLOT(devfn), PCI_FUNC(devfn));
  140.86 +           PCI_SLOT(devfn), PCI_FUNC(devfn));
  140.87  
  140.88  out:
  140.89      write_unlock(&pcidevs_lock);
  140.90 @@ -131,27 +136,66 @@ int pci_remove_device(u8 bus, u8 devfn)
  140.91      write_lock(&pcidevs_lock);
  140.92      list_for_each_entry ( pdev, &alldevs_list, alldevs_list )
  140.93          if ( pdev->bus == bus && pdev->devfn == devfn )
  140.94 -	{
  140.95 -	    spin_lock(&pdev->lock);
  140.96 -	    ret = iommu_remove_device(pdev);
  140.97 -	    if ( pdev->domain )
  140.98 -		list_del(&pdev->domain_list);
  140.99 -	    pci_cleanup_msi(pdev);
 140.100 -	    free_pdev(pdev);
 140.101 -	    printk(XENLOG_DEBUG "PCI remove device %02x:%02x.%x\n", bus,
 140.102 -		   PCI_SLOT(devfn), PCI_FUNC(devfn));
 140.103 -	    break;
 140.104 -	}
 140.105 +        {
 140.106 +            spin_lock(&pdev->lock);
 140.107 +            ret = iommu_remove_device(pdev);
 140.108 +            if ( pdev->domain )
 140.109 +                list_del(&pdev->domain_list);
 140.110 +            pci_cleanup_msi(pdev);
 140.111 +            free_pdev(pdev);
 140.112 +            printk(XENLOG_DEBUG "PCI remove device %02x:%02x.%x\n", bus,
 140.113 +                   PCI_SLOT(devfn), PCI_FUNC(devfn));
 140.114 +            break;
 140.115 +        }
 140.116  
 140.117      write_unlock(&pcidevs_lock);
 140.118      return ret;
 140.119  }
 140.120  
 140.121 +static void pci_clean_dpci_irqs(struct domain *d)
 140.122 +{
 140.123 +    struct hvm_irq_dpci *hvm_irq_dpci = domain_get_irq_dpci(d);
 140.124 +    uint32_t i;
 140.125 +    struct list_head *digl_list, *tmp;
 140.126 +    struct dev_intx_gsi_link *digl;
 140.127 +
 140.128 +    if ( !iommu_enabled )
 140.129 +        return;
 140.130 +
 140.131 +    if ( !is_hvm_domain(d) && !need_iommu(d) )
 140.132 +        return;
 140.133 +
 140.134 +    if ( hvm_irq_dpci != NULL )
 140.135 +    {
 140.136 +        for ( i = 0; i < NR_IRQS; i++ )
 140.137 +        {
 140.138 +            if ( !(hvm_irq_dpci->mirq[i].flags & HVM_IRQ_DPCI_VALID) )
 140.139 +                continue;
 140.140 +
 140.141 +            pirq_guest_unbind(d, i);
 140.142 +            kill_timer(&hvm_irq_dpci->hvm_timer[irq_to_vector(i)]);
 140.143 +
 140.144 +            list_for_each_safe ( digl_list, tmp,
 140.145 +                                 &hvm_irq_dpci->mirq[i].digl_list )
 140.146 +            {
 140.147 +                digl = list_entry(digl_list,
 140.148 +                                  struct dev_intx_gsi_link, list);
 140.149 +                list_del(&digl->list);
 140.150 +                xfree(digl);
 140.151 +            }
 140.152 +        }
 140.153 +
 140.154 +        d->arch.hvm_domain.irq.dpci = NULL;
 140.155 +        xfree(hvm_irq_dpci);
 140.156 +    }
 140.157 +}
 140.158 +
 140.159  void pci_release_devices(struct domain *d)
 140.160  {
 140.161      struct pci_dev *pdev;
 140.162      u8 bus, devfn;
 140.163  
 140.164 +    pci_clean_dpci_irqs(d);
 140.165      while ( (pdev = pci_lock_domain_pdev(d, -1, -1)) )
 140.166      {
 140.167          pci_cleanup_msi(pdev);
 140.168 @@ -171,14 +215,14 @@ static void dump_pci_devices(unsigned ch
 140.169  
 140.170      list_for_each_entry ( pdev, &alldevs_list, alldevs_list )
 140.171      {
 140.172 -	spin_lock(&pdev->lock);
 140.173 +        spin_lock(&pdev->lock);
 140.174          printk("%02x:%02x.%x - dom %-3d - MSIs < ",
 140.175                 pdev->bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
 140.176                 pdev->domain ? pdev->domain->domain_id : -1);
 140.177 -	list_for_each_entry ( msi, &pdev->msi_list, list )
 140.178 -	    printk("%d ", msi->vector);
 140.179 -	printk(">\n");
 140.180 -	spin_unlock(&pdev->lock);
 140.181 +        list_for_each_entry ( msi, &pdev->msi_list, list )
 140.182 +               printk("%d ", msi->vector);
 140.183 +        printk(">\n");
 140.184 +        spin_unlock(&pdev->lock);
 140.185      }
 140.186  
 140.187      read_unlock(&pcidevs_lock);
   141.1 --- a/xen/drivers/passthrough/vtd/dmar.c	Thu Aug 07 11:47:34 2008 +0900
   141.2 +++ b/xen/drivers/passthrough/vtd/dmar.c	Thu Aug 07 11:57:34 2008 +0900
   141.3 @@ -238,15 +238,15 @@ static int __init acpi_parse_dev_scope(v
   141.4              bus = pci_conf_read8(bus, path->dev, path->fn, PCI_SECONDARY_BUS);
   141.5              path++;
   141.6          }
   141.7 -        
   141.8 +
   141.9          switch ( acpi_scope->dev_type )
  141.10          {
  141.11          case ACPI_DEV_P2PBRIDGE:
  141.12          {
  141.13              sec_bus = pci_conf_read8(
  141.14 -		bus, path->dev, path->fn, PCI_SECONDARY_BUS);
  141.15 +                bus, path->dev, path->fn, PCI_SECONDARY_BUS);
  141.16              sub_bus = pci_conf_read8(
  141.17 -		bus, path->dev, path->fn, PCI_SUBORDINATE_BUS);
  141.18 +                bus, path->dev, path->fn, PCI_SUBORDINATE_BUS);
  141.19              dprintk(XENLOG_INFO VTDPREFIX,
  141.20                      "found bridge: bdf = %x:%x.%x  sec = %x  sub = %x\n",
  141.21                      bus, path->dev, path->fn, sec_bus, sub_bus);
  141.22 @@ -255,7 +255,7 @@ static int __init acpi_parse_dev_scope(v
  141.23              break;
  141.24          }
  141.25  
  141.26 -	case ACPI_DEV_MSI_HPET:
  141.27 +        case ACPI_DEV_MSI_HPET:
  141.28              dprintk(XENLOG_INFO VTDPREFIX, "found MSI HPET: bdf = %x:%x.%x\n",
  141.29                      bus, path->dev, path->fn);
  141.30              scope->devices[didx++] = PCI_BDF(bus, path->dev, path->fn);
  141.31 @@ -305,13 +305,6 @@ acpi_parse_one_drhd(struct acpi_dmar_ent
  141.32      int ret = 0;
  141.33      static int include_all = 0;
  141.34  
  141.35 -    if ( include_all )
  141.36 -    {
  141.37 -        dprintk(XENLOG_WARNING VTDPREFIX,
  141.38 -                "DMAR unit with INCLUDE_ALL is not not the last unit.\n");
  141.39 -        return -EINVAL;
  141.40 -    }
  141.41 -
  141.42      dmaru = xmalloc(struct acpi_drhd_unit);
  141.43      if ( !dmaru )
  141.44          return -ENOMEM;
  141.45 @@ -331,6 +324,13 @@ acpi_parse_one_drhd(struct acpi_dmar_ent
  141.46      if ( dmaru->include_all )
  141.47      {
  141.48          dprintk(XENLOG_INFO VTDPREFIX, "found INCLUDE_ALL\n");
  141.49 +        /* Only allow one INCLUDE_ALL */
  141.50 +        if ( include_all )
  141.51 +        {
  141.52 +            dprintk(XENLOG_WARNING VTDPREFIX,
  141.53 +                    "Only one INCLUDE_ALL device scope is allowed\n");
  141.54 +            ret = -EINVAL;
  141.55 +        }
  141.56          include_all = 1;
  141.57      }
  141.58  
  141.59 @@ -349,6 +349,12 @@ acpi_parse_one_rmrr(struct acpi_dmar_ent
  141.60      void *dev_scope_start, *dev_scope_end;
  141.61      int ret = 0;
  141.62  
  141.63 +    if ( rmrr->base_address >= rmrr->end_address )
  141.64 +    {
  141.65 +        dprintk(XENLOG_ERR VTDPREFIX, "RMRR is incorrect.\n");
  141.66 +        return -EFAULT;
  141.67 +    }
  141.68 +
  141.69      rmrru = xmalloc(struct acpi_rmrr_unit);
  141.70      if ( !rmrru )
  141.71          return -ENOMEM;
  141.72 @@ -390,7 +396,8 @@ acpi_parse_one_atsr(struct acpi_dmar_ent
  141.73          ret = acpi_parse_dev_scope(dev_scope_start, dev_scope_end,
  141.74                                     atsru, ATSR_TYPE);
  141.75      }
  141.76 -    else {
  141.77 +    else
  141.78 +    {
  141.79          dprintk(XENLOG_INFO VTDPREFIX, "found ALL_PORTS\n");
  141.80          /* Only allow one ALL_PORTS */
  141.81          if ( all_ports )
  141.82 @@ -420,6 +427,9 @@ static int __init acpi_parse_dmar(struct
  141.83      if ( !dmar->width )
  141.84      {
  141.85          dprintk(XENLOG_WARNING VTDPREFIX, "Zero: Invalid DMAR width\n");
  141.86 +        if ( force_iommu )
  141.87 +            panic("acpi_parse_dmar: Invalid DMAR width,"
  141.88 +                  " crash Xen for security purpose!\n");
  141.89          return -EINVAL;
  141.90      }
  141.91  
  141.92 @@ -461,8 +471,15 @@ static int __init acpi_parse_dmar(struct
  141.93  
  141.94      if ( ret )
  141.95      {
  141.96 -        printk(XENLOG_WARNING "Failed to parse ACPI DMAR.  Disabling VT-d.\n");
  141.97 -        disable_all_dmar_units();
  141.98 +        if ( force_iommu )
  141.99 +            panic("acpi_parse_dmar: Failed to parse ACPI DMAR,"
 141.100 +                  " crash Xen for security purpose!\n");
 141.101 +        else
 141.102 +        {
 141.103 +            printk(XENLOG_WARNING
 141.104 +                   "Failed to parse ACPI DMAR.  Disabling VT-d.\n");
 141.105 +            disable_all_dmar_units();
 141.106 +        }
 141.107      }
 141.108  
 141.109      return ret;
 141.110 @@ -473,14 +490,16 @@ int acpi_dmar_init(void)
 141.111      int rc;
 141.112  
 141.113      rc = -ENODEV;
 141.114 +    if ( force_iommu )
 141.115 +        iommu_enabled = 1;
 141.116 +
 141.117      if ( !iommu_enabled )
 141.118          goto fail;
 141.119  
 141.120 -    if ( (rc = vtd_hw_check()) != 0 )
 141.121 +    rc = acpi_table_parse(ACPI_SIG_DMAR, acpi_parse_dmar);
 141.122 +    if ( rc )
 141.123          goto fail;
 141.124  
 141.125 -    acpi_table_parse(ACPI_SIG_DMAR, acpi_parse_dmar);
 141.126 -
 141.127      rc = -ENODEV;
 141.128      if ( list_empty(&acpi_drhd_units) )
 141.129          goto fail;
 141.130 @@ -490,6 +509,10 @@ int acpi_dmar_init(void)
 141.131      return 0;
 141.132  
 141.133   fail:
 141.134 +    if ( force_iommu )
 141.135 +        panic("acpi_dmar_init: acpi_dmar_init failed,"
 141.136 +              " crash Xen for security purpose!\n");
 141.137 +
 141.138      vtd_enabled = 0;
 141.139      return -ENODEV;
 141.140  }
   142.1 --- a/xen/drivers/passthrough/vtd/extern.h	Thu Aug 07 11:47:34 2008 +0900
   142.2 +++ b/xen/drivers/passthrough/vtd/extern.h	Thu Aug 07 11:57:34 2008 +0900
   142.3 @@ -28,6 +28,7 @@ extern struct ir_ctrl *ir_ctrl;
   142.4  
   142.5  void print_iommu_regs(struct acpi_drhd_unit *drhd);
   142.6  void print_vtd_entries(struct iommu *iommu, int bus, int devfn, u64 gmfn);
   142.7 +void dump_iommu_info(unsigned char key);
   142.8  
   142.9  int qinval_setup(struct iommu *iommu);
  142.10  int intremap_setup(struct iommu *iommu);
   143.1 --- a/xen/drivers/passthrough/vtd/iommu.c	Thu Aug 07 11:47:34 2008 +0900
   143.2 +++ b/xen/drivers/passthrough/vtd/iommu.c	Thu Aug 07 11:57:34 2008 +0900
   143.3 @@ -28,6 +28,7 @@
   143.4  #include <xen/time.h>
   143.5  #include <xen/pci.h>
   143.6  #include <xen/pci_regs.h>
   143.7 +#include <xen/keyhandler.h>
   143.8  #include <asm/paging.h>
   143.9  #include <asm/msi.h>
  143.10  #include "iommu.h"
  143.11 @@ -278,8 +279,8 @@ static void iommu_flush_write_buffer(str
  143.12          if ( !(val & DMA_GSTS_WBFS) )
  143.13              break;
  143.14          if ( NOW() > start_time + DMAR_OPERATION_TIMEOUT )
  143.15 -            panic("DMAR hardware is malfunctional,"
  143.16 -                  " please disable IOMMU\n");
  143.17 +            panic("%s: DMAR hardware is malfunctional,"
  143.18 +                  " please disable IOMMU\n", __func__);
  143.19          cpu_relax();
  143.20      }
  143.21      spin_unlock_irqrestore(&iommu->register_lock, flag);
  143.22 @@ -339,7 +340,8 @@ static int flush_context_reg(
  143.23          if ( !(val & DMA_CCMD_ICC) )
  143.24              break;
  143.25          if ( NOW() > start_time + DMAR_OPERATION_TIMEOUT )
  143.26 -            panic("DMAR hardware is malfunctional, please disable IOMMU\n");
  143.27 +            panic("%s: DMAR hardware is malfunctional,"
  143.28 +                  " please disable IOMMU\n", __func__);
  143.29          cpu_relax();
  143.30      }
  143.31      spin_unlock_irqrestore(&iommu->register_lock, flag);
  143.32 @@ -436,20 +438,20 @@ static int flush_iotlb_reg(void *_iommu,
  143.33          if ( !(val & DMA_TLB_IVT) )
  143.34              break;
  143.35          if ( NOW() > start_time + DMAR_OPERATION_TIMEOUT )
  143.36 -            panic("DMAR hardware is malfunctional, please disable IOMMU\n");
  143.37 +            panic("%s: DMAR hardware is malfunctional,"
  143.38 +                  " please disable IOMMU\n", __func__);
  143.39          cpu_relax();
  143.40      }
  143.41      spin_unlock_irqrestore(&am