ia64/xen-unstable

changeset 14510:49ec3725d0c0

Merge with xen-unstable.hg.
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
author Hollis Blanchard <hollisb@us.ibm.com>
date Wed Mar 21 18:08:31 2007 -0500 (2007-03-21)
parents 2c087916aaba 3fd9b0c71b8c
children 4e874484f4da
files tools/libxc/Makefile tools/libxc/xc_dom_x86.c tools/python/xen/lowlevel/xc/xc.c tools/python/xen/xend/image.py xen/arch/powerpc/setup.c xen/include/asm-x86/hvm/svm/vmmcall.h
line diff
     1.1 --- a/Config.mk	Wed Mar 21 17:03:00 2007 -0500
     1.2 +++ b/Config.mk	Wed Mar 21 18:08:31 2007 -0500
     1.3 @@ -36,6 +36,12 @@ endif
     1.4  cc-option = $(shell if test -z "`$(1) $(2) -S -o /dev/null -xc \
     1.5                /dev/null 2>&1`"; then echo "$(2)"; else echo "$(3)"; fi ;)
     1.6  
     1.7 +# cc-ver
     1.8 +# Usage: ifeq ($(call cc-ver,$(CC),0x030400),y)
     1.9 +cc-ver = $(shell if [ $$((`$(1) -dumpversion | awk -F. \
    1.10 +           '{ printf "0x%02x%02x%02x", $$1, $$2, $$3}'`)) -ge $$(($(2))) ]; \
    1.11 +           then echo y; else echo n; fi ;)
    1.12 +
    1.13  ifneq ($(debug),y)
    1.14  CFLAGS += -DNDEBUG
    1.15  else
     2.1 --- a/buildconfigs/conf.linux-native/00_xen_to_native	Wed Mar 21 17:03:00 2007 -0500
     2.2 +++ b/buildconfigs/conf.linux-native/00_xen_to_native	Wed Mar 21 18:08:31 2007 -0500
     2.3 @@ -74,8 +74,10 @@ CONFIG_SERIAL_CORE_CONSOLE=y
     2.4  # CONFIG_XEN_DISABLE_SERIAL is not set
     2.5  # CONFIG_XEN_SYSFS is not set
     2.6  # CONFIG_XEN_COMPAT_030002_AND_LATER is not set
     2.7 +# CONFIG_XEN_COMPAT_030004_AND_LATER is not set
     2.8  # CONFIG_XEN_COMPAT_LATEST_ONLY is not set
     2.9  # CONFIG_XEN_COMPAT_030002 is not set
    2.10 +# CONFIG_XEN_COMPAT_030004 is not set
    2.11  # CONFIG_HAVE_ARCH_ALLOC_SKB is not set
    2.12  # CONFIG_HAVE_ARCH_DEV_ALLOC_SKB is not set
    2.13  # CONFIG_NO_IDLE_HZ is not set
     3.1 --- a/buildconfigs/linux-defconfig_xen0_ia64	Wed Mar 21 17:03:00 2007 -0500
     3.2 +++ b/buildconfigs/linux-defconfig_xen0_ia64	Wed Mar 21 18:08:31 2007 -0500
     3.3 @@ -1619,7 +1619,7 @@ CONFIG_CRYPTO_DES=y
     3.4  CONFIG_XEN_BALLOON=y
     3.5  CONFIG_XEN_REBOOT=y
     3.6  # CONFIG_XEN_SMPBOOT is not set
     3.7 -CONFIG_XEN_INTERFACE_VERSION=0x00030203
     3.8 +CONFIG_XEN_INTERFACE_VERSION=0x00030205
     3.9  
    3.10  #
    3.11  # XEN
    3.12 @@ -1647,8 +1647,10 @@ CONFIG_XEN_NETDEV_FRONTEND=y
    3.13  CONFIG_XEN_DISABLE_SERIAL=y
    3.14  CONFIG_XEN_SYSFS=y
    3.15  CONFIG_XEN_COMPAT_030002_AND_LATER=y
    3.16 +# CONFIG_XEN_COMPAT_030004_AND_LATER is not set
    3.17  # CONFIG_XEN_COMPAT_LATEST_ONLY is not set
    3.18  CONFIG_XEN_COMPAT_030002=y
    3.19 +CONFIG_XEN_COMPAT_030004=y
    3.20  CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
    3.21  CONFIG_NO_IDLE_HZ=y
    3.22  CONFIG_XEN_DEVMEM=y
     4.1 --- a/buildconfigs/linux-defconfig_xen0_x86_32	Wed Mar 21 17:03:00 2007 -0500
     4.2 +++ b/buildconfigs/linux-defconfig_xen0_x86_32	Wed Mar 21 18:08:31 2007 -0500
     4.3 @@ -1384,7 +1384,7 @@ CONFIG_CRYPTO_CRC32C=m
     4.4  #
     4.5  # CONFIG_CRYPTO_DEV_PADLOCK is not set
     4.6  CONFIG_XEN=y
     4.7 -CONFIG_XEN_INTERFACE_VERSION=0x00030203
     4.8 +CONFIG_XEN_INTERFACE_VERSION=0x00030205
     4.9  
    4.10  #
    4.11  # XEN
    4.12 @@ -1411,8 +1411,10 @@ CONFIG_XEN_SCRUB_PAGES=y
    4.13  CONFIG_XEN_DISABLE_SERIAL=y
    4.14  CONFIG_XEN_SYSFS=y
    4.15  CONFIG_XEN_COMPAT_030002_AND_LATER=y
    4.16 +# CONFIG_XEN_COMPAT_030004_AND_LATER is not set
    4.17  # CONFIG_XEN_COMPAT_LATEST_ONLY is not set
    4.18  CONFIG_XEN_COMPAT_030002=y
    4.19 +CONFIG_XEN_COMPAT_030004=y
    4.20  CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
    4.21  CONFIG_NO_IDLE_HZ=y
    4.22  CONFIG_XEN_UTIL=y
     5.1 --- a/buildconfigs/linux-defconfig_xen0_x86_64	Wed Mar 21 17:03:00 2007 -0500
     5.2 +++ b/buildconfigs/linux-defconfig_xen0_x86_64	Wed Mar 21 18:08:31 2007 -0500
     5.3 @@ -1334,7 +1334,7 @@ CONFIG_CRYPTO_CRC32C=m
     5.4  # Hardware crypto devices
     5.5  #
     5.6  CONFIG_XEN=y
     5.7 -CONFIG_XEN_INTERFACE_VERSION=0x00030203
     5.8 +CONFIG_XEN_INTERFACE_VERSION=0x00030205
     5.9  
    5.10  #
    5.11  # XEN
    5.12 @@ -1361,8 +1361,10 @@ CONFIG_XEN_SCRUB_PAGES=y
    5.13  CONFIG_XEN_DISABLE_SERIAL=y
    5.14  CONFIG_XEN_SYSFS=y
    5.15  CONFIG_XEN_COMPAT_030002_AND_LATER=y
    5.16 +# CONFIG_XEN_COMPAT_030004_AND_LATER is not set
    5.17  # CONFIG_XEN_COMPAT_LATEST_ONLY is not set
    5.18  CONFIG_XEN_COMPAT_030002=y
    5.19 +CONFIG_XEN_COMPAT_030004=y
    5.20  CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
    5.21  CONFIG_NO_IDLE_HZ=y
    5.22  CONFIG_XEN_UTIL=y
     6.1 --- a/buildconfigs/linux-defconfig_xenU_ia64	Wed Mar 21 17:03:00 2007 -0500
     6.2 +++ b/buildconfigs/linux-defconfig_xenU_ia64	Wed Mar 21 18:08:31 2007 -0500
     6.3 @@ -1471,7 +1471,7 @@ CONFIG_CRYPTO_DES=y
     6.4  CONFIG_XEN_BALLOON=y
     6.5  CONFIG_XEN_REBOOT=y
     6.6  # CONFIG_XEN_SMPBOOT is not set
     6.7 -CONFIG_XEN_INTERFACE_VERSION=0x00030203
     6.8 +CONFIG_XEN_INTERFACE_VERSION=0x00030205
     6.9  
    6.10  #
    6.11  # XEN
    6.12 @@ -1489,8 +1489,10 @@ CONFIG_XEN_KEYBOARD=y
    6.13  # CONFIG_XEN_DISABLE_SERIAL is not set
    6.14  CONFIG_XEN_SYSFS=y
    6.15  CONFIG_XEN_COMPAT_030002_AND_LATER=y
    6.16 +# CONFIG_XEN_COMPAT_030004_AND_LATER is not set
    6.17  # CONFIG_XEN_COMPAT_LATEST_ONLY is not set
    6.18  CONFIG_XEN_COMPAT_030002=y
    6.19 +CONFIG_XEN_COMPAT_030004=y
    6.20  CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
    6.21  CONFIG_NO_IDLE_HZ=y
    6.22  CONFIG_XEN_DEVMEM=y
     7.1 --- a/buildconfigs/linux-defconfig_xenU_x86_32	Wed Mar 21 17:03:00 2007 -0500
     7.2 +++ b/buildconfigs/linux-defconfig_xenU_x86_32	Wed Mar 21 18:08:31 2007 -0500
     7.3 @@ -904,7 +904,7 @@ CONFIG_CRYPTO_CRC32C=m
     7.4  #
     7.5  # CONFIG_CRYPTO_DEV_PADLOCK is not set
     7.6  CONFIG_XEN=y
     7.7 -CONFIG_XEN_INTERFACE_VERSION=0x00030203
     7.8 +CONFIG_XEN_INTERFACE_VERSION=0x00030205
     7.9  
    7.10  #
    7.11  # XEN
    7.12 @@ -920,8 +920,10 @@ CONFIG_XEN_SCRUB_PAGES=y
    7.13  CONFIG_XEN_DISABLE_SERIAL=y
    7.14  CONFIG_XEN_SYSFS=y
    7.15  CONFIG_XEN_COMPAT_030002_AND_LATER=y
    7.16 +# CONFIG_XEN_COMPAT_030004_AND_LATER is not set
    7.17  # CONFIG_XEN_COMPAT_LATEST_ONLY is not set
    7.18  CONFIG_XEN_COMPAT_030002=y
    7.19 +CONFIG_XEN_COMPAT_030004=y
    7.20  CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
    7.21  CONFIG_NO_IDLE_HZ=y
    7.22  CONFIG_XEN_UTIL=y
     8.1 --- a/buildconfigs/linux-defconfig_xenU_x86_64	Wed Mar 21 17:03:00 2007 -0500
     8.2 +++ b/buildconfigs/linux-defconfig_xenU_x86_64	Wed Mar 21 18:08:31 2007 -0500
     8.3 @@ -1200,7 +1200,7 @@ CONFIG_CRYPTO_CRC32C=m
     8.4  # Hardware crypto devices
     8.5  #
     8.6  CONFIG_XEN=y
     8.7 -CONFIG_XEN_INTERFACE_VERSION=0x00030203
     8.8 +CONFIG_XEN_INTERFACE_VERSION=0x00030205
     8.9  
    8.10  #
    8.11  # XEN
    8.12 @@ -1216,8 +1216,10 @@ CONFIG_XEN_SCRUB_PAGES=y
    8.13  CONFIG_XEN_DISABLE_SERIAL=y
    8.14  CONFIG_XEN_SYSFS=y
    8.15  CONFIG_XEN_COMPAT_030002_AND_LATER=y
    8.16 +# CONFIG_XEN_COMPAT_030004_AND_LATER is not set
    8.17  # CONFIG_XEN_COMPAT_LATEST_ONLY is not set
    8.18  CONFIG_XEN_COMPAT_030002=y
    8.19 +CONFIG_XEN_COMPAT_030004=y
    8.20  CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
    8.21  CONFIG_NO_IDLE_HZ=y
    8.22  CONFIG_XEN_UTIL=y
     9.1 --- a/buildconfigs/linux-defconfig_xen_ia64	Wed Mar 21 17:03:00 2007 -0500
     9.2 +++ b/buildconfigs/linux-defconfig_xen_ia64	Wed Mar 21 18:08:31 2007 -0500
     9.3 @@ -1619,7 +1619,7 @@ CONFIG_CRYPTO_DES=y
     9.4  CONFIG_XEN_BALLOON=y
     9.5  CONFIG_XEN_REBOOT=y
     9.6  # CONFIG_XEN_SMPBOOT is not set
     9.7 -CONFIG_XEN_INTERFACE_VERSION=0x00030203
     9.8 +CONFIG_XEN_INTERFACE_VERSION=0x00030205
     9.9  
    9.10  #
    9.11  # XEN
    9.12 @@ -1648,8 +1648,10 @@ CONFIG_XEN_KEYBOARD=y
    9.13  CONFIG_XEN_DISABLE_SERIAL=y
    9.14  CONFIG_XEN_SYSFS=y
    9.15  CONFIG_XEN_COMPAT_030002_AND_LATER=y
    9.16 +# CONFIG_XEN_COMPAT_030004_AND_LATER is not set
    9.17  # CONFIG_XEN_COMPAT_LATEST_ONLY is not set
    9.18  CONFIG_XEN_COMPAT_030002=y
    9.19 +CONFIG_XEN_COMPAT_030004=y
    9.20  CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
    9.21  CONFIG_NO_IDLE_HZ=y
    9.22  CONFIG_XEN_DEVMEM=y
    10.1 --- a/buildconfigs/linux-defconfig_xen_x86_32	Wed Mar 21 17:03:00 2007 -0500
    10.2 +++ b/buildconfigs/linux-defconfig_xen_x86_32	Wed Mar 21 18:08:31 2007 -0500
    10.3 @@ -3242,7 +3242,7 @@ CONFIG_CRYPTO_TEST=m
    10.4  #
    10.5  # CONFIG_CRYPTO_DEV_PADLOCK is not set
    10.6  CONFIG_XEN=y
    10.7 -CONFIG_XEN_INTERFACE_VERSION=0x00030203
    10.8 +CONFIG_XEN_INTERFACE_VERSION=0x00030205
    10.9  
   10.10  #
   10.11  # XEN
   10.12 @@ -3271,8 +3271,10 @@ CONFIG_XEN_SCRUB_PAGES=y
   10.13  CONFIG_XEN_DISABLE_SERIAL=y
   10.14  CONFIG_XEN_SYSFS=y
   10.15  CONFIG_XEN_COMPAT_030002_AND_LATER=y
   10.16 +# CONFIG_XEN_COMPAT_030004_AND_LATER is not set
   10.17  # CONFIG_XEN_COMPAT_LATEST_ONLY is not set
   10.18  CONFIG_XEN_COMPAT_030002=y
   10.19 +CONFIG_XEN_COMPAT_030004=y
   10.20  CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
   10.21  CONFIG_NO_IDLE_HZ=y
   10.22  CONFIG_XEN_UTIL=y
    11.1 --- a/buildconfigs/linux-defconfig_xen_x86_64	Wed Mar 21 17:03:00 2007 -0500
    11.2 +++ b/buildconfigs/linux-defconfig_xen_x86_64	Wed Mar 21 18:08:31 2007 -0500
    11.3 @@ -3072,7 +3072,7 @@ CONFIG_CRYPTO_TEST=m
    11.4  # Hardware crypto devices
    11.5  #
    11.6  CONFIG_XEN=y
    11.7 -CONFIG_XEN_INTERFACE_VERSION=0x00030203
    11.8 +CONFIG_XEN_INTERFACE_VERSION=0x00030205
    11.9  
   11.10  #
   11.11  # XEN
   11.12 @@ -3101,8 +3101,10 @@ CONFIG_XEN_SCRUB_PAGES=y
   11.13  CONFIG_XEN_DISABLE_SERIAL=y
   11.14  CONFIG_XEN_SYSFS=y
   11.15  CONFIG_XEN_COMPAT_030002_AND_LATER=y
   11.16 +# CONFIG_XEN_COMPAT_030004_AND_LATER is not set
   11.17  # CONFIG_XEN_COMPAT_LATEST_ONLY is not set
   11.18  CONFIG_XEN_COMPAT_030002=y
   11.19 +CONFIG_XEN_COMPAT_030004=y
   11.20  CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
   11.21  CONFIG_NO_IDLE_HZ=y
   11.22  CONFIG_XEN_UTIL=y
    12.1 --- a/docs/man/xm.pod.1	Wed Mar 21 17:03:00 2007 -0500
    12.2 +++ b/docs/man/xm.pod.1	Wed Mar 21 18:08:31 2007 -0500
    12.3 @@ -619,7 +619,7 @@ devices, or by device id, such as 0x1400
    12.4  =item I<mode>
    12.5  
    12.6  The access mode for the device from the guest domain.  Supported modes
    12.7 -are I<rw> (read/write) or I<ro> (read-only).
    12.8 +are I<w> (read/write) or I<r> (read-only).
    12.9  
   12.10  =item I<bedomain-id>
   12.11  
    13.1 --- a/docs/misc/dump-core-format.txt	Wed Mar 21 17:03:00 2007 -0500
    13.2 +++ b/docs/misc/dump-core-format.txt	Wed Mar 21 18:08:31 2007 -0500
    13.3 @@ -80,8 +80,7 @@ Currently the following sections are def
    13.4                          gmfn:   machine physical frame number
    13.5                  The size of arrays is stored in xch_nr_pages member of header
    13.6                  note descriptor in .note.Xen note section.
    13.7 -                There is no rule about the order. Analysis tools must no rely
    13.8 -                on its order.
    13.9 +                The entryies are stored in pfn-ascending order.
   13.10                  This section must exist when the domain is non auto
   13.11                  translated physmap mode. Currently x86 paravirtualized domain.
   13.12  
   13.13 @@ -94,8 +93,7 @@ Currently the following sections are def
   13.14                  in .xen_pages section.
   13.15                  The size of arrays is stored in xch_nr_pages member of header
   13.16                  note descriptor in .note.Xen note section.
   13.17 -                There is no rule about the order. Analysis tools must no rely
   13.18 -                on its order.
   13.19 +                The entries are stored in ascending order.
   13.20                  This section must exist when the domain is auto translated
   13.21                  physmap mode. Currently x86 full virtualized domain and
   13.22                  ia64 domain.
   13.23 @@ -226,6 +224,8 @@ Currently only (major, minor) = (0, 1) i
   13.24  [When the format is changed, it would be described here.]
   13.25  
   13.26  (0, 1) update
   13.27 +- .xen_p2m, .xen_pfn section
   13.28 +  Arrays must be in pfn ascending order for efficient looking up.
   13.29  - EI_CLASS member of elf header was changed to ELFCLASS64 independent of
   13.30    architecture. This is mainly for x86_32pae.
   13.31    The format version isn't bumped because analysis tools can distinguish it.
    14.1 --- a/docs/src/user.tex	Wed Mar 21 17:03:00 2007 -0500
    14.2 +++ b/docs/src/user.tex	Wed Mar 21 18:08:31 2007 -0500
    14.3 @@ -3179,6 +3179,11 @@ editing \path{grub.conf}.
    14.4    one of 80x25, 80x28, 80x30, 80x34, 80x43, 80x50, 80x60.
    14.5    \item[ keep ] Keep the VGA console even after domain 0 boots.
    14.6    \end{description}
    14.7 +\item [ console\_to\_ring ] Place guest console output into the
    14.8 +  hypervisor console ring buffer. This is disabled by default.
    14.9 +  When enabled, both hypervisor output and guest console output
   14.10 +  is available from the ring buffer. This can be useful for logging
   14.11 +  and/or remote presentation of console data.
   14.12  \item [ sync\_console ] Force synchronous console output. This is
   14.13    useful if you system fails unexpectedly before it has sent all
   14.14    available output to the console. In most cases Xen will
    15.1 --- a/docs/xen-api/coversheet.tex	Wed Mar 21 17:03:00 2007 -0500
    15.2 +++ b/docs/xen-api/coversheet.tex	Wed Mar 21 18:08:31 2007 -0500
    15.3 @@ -47,4 +47,4 @@ Date: \datestring{}
    15.4  \legalnotice{}
    15.5  
    15.6  \newpage
    15.7 -\pagestyle{plain}
    15.8 \ No newline at end of file
    15.9 +\pagestyle{fancy}
   15.10 \ No newline at end of file
    16.1 --- a/docs/xen-api/presentation.tex	Wed Mar 21 17:03:00 2007 -0500
    16.2 +++ b/docs/xen-api/presentation.tex	Wed Mar 21 18:08:31 2007 -0500
    16.3 @@ -57,14 +57,14 @@ type $t_1$ to values of type $t_2$.
    16.4  \end{itemize}
    16.5  
    16.6  Note that there are a number of cases where {\em Ref}s are {\em doubly
    16.7 -linked\/}---e.g.\ a VM has a field called {\tt groups} of type
    16.8 -$(\mathit{VMGroup}~\mathit{Ref})~\mathit{Set}$; this field lists
    16.9 -the VMGroups that a particular VM is part of. Similarly, the VMGroups
   16.10 -class has a field called {\tt VMs} of type $(\mathit{VM}~{\mathit
   16.11 -Ref})~\mathit{Set}$ that contains the VMs that are part of a particular
   16.12 -VMGroup. These two fields are {\em bound together\/}, in the sense that
   16.13 -adding a new VMGroup to a VM causes the VMs field of the corresponding
   16.14 -VMGroup object to be updated automatically.
   16.15 +linked\/}---e.g.\ a VM has a field called {\tt VIFs} of type
   16.16 +$(\mathit{VIF}~\mathit{Ref})~\mathit{Set}$; this field lists
   16.17 +the network interfaces attached to a particular VM. Similarly, the VIF
   16.18 +class has a field called {\tt VM} of type $(\mathit{VM}~{\mathit
   16.19 +Ref})$ which references the VM to which the interface is connected.
   16.20 +These two fields are {\em bound together\/}, in the sense that
   16.21 +creating a new VIF causes the {\tt VIFs} field of the corresponding
   16.22 +VM object to be updated automatically.
   16.23  
   16.24  The API reference explicitly lists the fields that are
   16.25  bound together in this way. It also contains a diagram that shows
    17.1 --- a/docs/xen-api/todo.tex	Wed Mar 21 17:03:00 2007 -0500
    17.2 +++ b/docs/xen-api/todo.tex	Wed Mar 21 18:08:31 2007 -0500
    17.3 @@ -91,17 +91,10 @@ same subnet.
    17.4  
    17.5  \end{itemize}
    17.6  
    17.7 -\item TPM
    17.8 +\item ACM
    17.9  \begin{itemize}
   17.10  
   17.11 -\item Would it not be better to have a class TPM and a member TPMs ((TPM ref)
   17.12 -Set) containing an array of zero or one references to TPMs? I assume that
   17.13 -an empty array would make it clear that no TPM is associated with the VM
   17.14 -instead of encoding its existence into TPM/instance or TPM/backend
   17.15 -somehow. The current members instance and backend could then be moved into
   17.16 -the TPM class.
   17.17 -
   17.18 -\item Also a Xen system can be running an access control policy where each
   17.19 +\item A Xen system can be running an access control policy where each
   17.20  VM's run-time access to resources is restricted by the label it has been given
   17.21  compared to those of the resources. Currently a VM's configuration file may
   17.22  contain a line like access\_control[policy='$<$name of the system's
    18.1 --- a/docs/xen-api/vm-lifecycle.tex	Wed Mar 21 17:03:00 2007 -0500
    18.2 +++ b/docs/xen-api/vm-lifecycle.tex	Wed Mar 21 18:08:31 2007 -0500
    18.3 @@ -22,3 +22,19 @@
    18.4  
    18.5  Figure~\ref{fig-vm-lifecycle} shows the states that a VM can be in
    18.6  and the API calls that can be used to move the VM between these states.
    18.7 +
    18.8 +\section{VM boot parameters}
    18.9 +
   18.10 +The VM class contains a number of fields that control the way in which the VM is booted.
   18.11 +With reference to the fields defined in the VM class (see later in this document),
   18.12 +this section outlines the boot options available and the mechanisms provided for controlling them.
   18.13 +
   18.14 +VM booting is controlled by setting one of the two mutually exclusive groups: ``PV'', and ``HVM''.  If HVM.boot\_policy is the empty string, then paravirtual domain building and booting will be used; otherwise the VM will be loaded as an HVM domain, and booted using an emulated BIOS.
   18.15 +
   18.16 +When paravirtual booting is in use, the PV/bootloader field indicates the bootloader to use.  It may be ``pygrub'', in which case the platform's default installation of pygrub will be used, or a full path within the control domain to some other bootloader.  The other fields, PV/kernel, PV/ramdisk, PV/args and PV/bootloader\_args will be passed to the bootloader unmodified, and interpretation of those fields is then specific to the bootloader itself, including the possibility that the bootloader will ignore some or all of those given values. Finally the paths of all bootable disks are added to the bootloader commandline (a disk is bootable if its VBD has the bootable flag set). There may be zero, one or many bootable disks; the bootloader decides which disk (if any) to boot from.
   18.17 +
   18.18 +If the bootloader is pygrub, then the menu.lst is parsed if present in the guest's filesystem, otherwise the specified kernel and ramdisk are used, or an autodetected kernel is used if nothing is specified and autodetection is possible.  PV/args is appended to the kernel command line, no matter which mechanism is used for finding the kernel.
   18.19 +
   18.20 +If PV/bootloader is empty but PV/kernel is specified, then the kernel and ramdisk values will be treated as paths within the control domain.  If both PV/bootloader and PV/kernel are empty, then the behaviour is as if PV/bootloader was specified as ``pygrub''.
   18.21 +
   18.22 +When using HVM booting, HVM/boot\_policy and HVM/boot\_params specify the boot handling.  Only one policy is currently defined: ``BIOS order''.  In this case, HVM/boot\_params should contain one key-value pair ``order'' = ``N'' where N is the string that will be passed to QEMU.
   18.23 \ No newline at end of file
    19.1 --- a/docs/xen-api/wire-protocol.tex	Wed Mar 21 17:03:00 2007 -0500
    19.2 +++ b/docs/xen-api/wire-protocol.tex	Wed Mar 21 18:08:31 2007 -0500
    19.3 @@ -30,8 +30,13 @@ These types are mapped onto XML-RPC type
    19.4    \item Floats, Bools, DateTimes and Strings map directly to the XML-RPC {\tt
    19.5    double}, {\tt boolean}, {\tt dateTime.iso8601}, and {\tt string} elements.
    19.6  
    19.7 -  \item all our ``{\tt ref\_}'' types (e.g.\ {\tt ref\_vm} in the above
    19.8 -  example) map to XML-RPC's {\tt String} type.  The string itself is the OSF
    19.9 +  \item all ``{\tt ref\_}'' types are opaque references, encoded as the
   19.10 +  XML-RPC's {\tt String} type. Users of the API should not make assumptions
   19.11 +  about the concrete form of these strings and should not expect them to
   19.12 +  remain valid after the client's session with the server has terminated.
   19.13 +
   19.14 +  \item fields named ``{\tt uuid}'' of type ``{\tt String}'' are mapped to
   19.15 +  the XML-RPC {\tt String} type. The string itself is the OSF
   19.16    DCE UUID presentation format (as output by {\tt uuidgen}, etc).
   19.17  
   19.18    \item ints are all assumed to be 64-bit in our API and are encoded as a
   19.19 @@ -84,6 +89,32 @@ These types are mapped onto XML-RPC type
   19.20  
   19.21  \end{itemize}
   19.22  
   19.23 +\subsection{Note on References vs UUIDs}
   19.24 +
   19.25 +References are opaque types --- encoded as XML-RPC strings on the wire --- understood
   19.26 +only by the particular server which generated them. Servers are free to choose
   19.27 +any concrete representation they find convenient; clients should not make any 
   19.28 +assumptions or attempt to parse the string contents. References are not guaranteed
   19.29 +to be permanent identifiers for objects; clients should not assume that references 
   19.30 +generated during one session are valid for any future session. References do not
   19.31 +allow objects to be compared for equality. Two references to the same object are
   19.32 +not guaranteed to be textually identical.
   19.33 +
   19.34 +UUIDs are intended to be permanent names for objects. They are
   19.35 +guaranteed to be in the OSF DCE UUID presentation format (as output by {\tt uuidgen}.
   19.36 +Clients may store UUIDs on disk and use them to lookup objects in subsequent sessions
   19.37 +with the server. Clients may also test equality on objects by comparing UUID strings.
   19.38 +
   19.39 +The API provides mechanisms
   19.40 +for translating between UUIDs and opaque references. Each class that contains a UUID
   19.41 +field provides:
   19.42 +\begin{itemize}
   19.43 +\item  A ``{\tt get\_by\_uuid}'' method that takes a UUID, $u$, and returns an opaque reference
   19.44 +to the server-side object that has UUID=$u$; 
   19.45 +\item A {\tt get\_uuid} function (a regular ``field getter'' RPC) that takes an opaque reference,
   19.46 +$r$, and returns the UUID of the server-side object that is referenced by $r$.
   19.47 +\end{itemize}
   19.48 +
   19.49  \subsection{Return Values/Status Codes}
   19.50  \label{synchronous-result}
   19.51  
   19.52 @@ -138,7 +169,7 @@ may look like this:
   19.53  
   19.54  \subsection{Transport Layer}
   19.55  
   19.56 -We ought to support at least
   19.57 +The following transport layers are currently supported:
   19.58  \begin{itemize}
   19.59  \item HTTP/S for remote administration
   19.60  \item HTTP over Unix domain sockets for local administration
   19.61 @@ -247,13 +278,12 @@ call takes the session token as the only
   19.62  \begin{verbatim}
   19.63  >>> all_vms = host.get_resident_VMs(session)['Value']
   19.64  >>> all_vms
   19.65 -['b7b92d9e-d442-4710-92a5-ab039fd7d89b', '23e1e837-abbf-4675-b077-d4007989b0cc',
   19.66 -  '2045dbc0-0734-4eea-9cb2-b8218c6b5bf2', '3202ae18-a046-4c32-9fda-e32e9631866e']
   19.67 +['OpaqueRef:1', 'OpaqueRef:2', 'OpaqueRef:3', 'OpaqueRef:4' ]
   19.68  \end{verbatim}
   19.69  
   19.70 -The VM references here are UUIDs, though they may not be that simple in the
   19.71 -future, and you should treat them as opaque strings.  Once a reference to a VM
   19.72 -has been acquired a lifecycle operation may be invoked:
   19.73 +The VM references here have the form {\tt OpaqueRef:X}, though they may not be 
   19.74 +that simple in the future, and you should treat them as opaque strings.  
   19.75 +Once a reference to a VM has been acquired a lifecycle operation may be invoked:
   19.76  
   19.77  \begin{verbatim}
   19.78  >>> xen.VM.start(session, all_vms[3], False)
    20.1 --- a/docs/xen-api/xenapi-datamodel.tex	Wed Mar 21 17:03:00 2007 -0500
    20.2 +++ b/docs/xen-api/xenapi-datamodel.tex	Wed Mar 21 18:08:31 2007 -0500
    20.3 @@ -231,7 +231,7 @@ Quals & Field & Type & Description \\
    20.4  $\mathit{RO}_\mathit{run}$ &  {\tt last\_active} & int & Timestamp for last time session was active \\
    20.5  \hline
    20.6  \end{longtable}
    20.7 -\subsection{Additional RPCs associated with class: session}
    20.8 +\subsection{RPCs associated with class: session}
    20.9  \subsubsection{RPC name:~login\_with\_password}
   20.10  
   20.11  {\bf Overview:} 
   20.12 @@ -505,7 +505,7 @@ Quals & Field & Type & Description \\
   20.13  $\mathit{RO}_\mathit{run}$ &  {\tt allowed\_operations} & (task\_allowed\_operations) Set & Operations allowed on this task \\
   20.14  \hline
   20.15  \end{longtable}
   20.16 -\subsection{Additional RPCs associated with class: task}
   20.17 +\subsection{RPCs associated with class: task}
   20.18  \subsubsection{RPC name:~cancel}
   20.19  
   20.20  {\bf Overview:} 
   20.21 @@ -1022,40 +1022,7 @@ references to objects with match names
   20.22  \hline
   20.23  \multicolumn{1}{|l}{Name} & \multicolumn{3}{l|}{\bf VM} \\
   20.24  \multicolumn{1}{|l}{Description} & \multicolumn{3}{l|}{\parbox{11cm}{\em A
   20.25 -virtual machine (or 'guest').
   20.26 -
   20.27 -VM booting is controlled by setting one of the two mutually exclusive
   20.28 -groups: "PV", and "HVM".  If HVM.boot\_policy is the empty string, then
   20.29 -paravirtual domain building and booting will be used; otherwise the VM will
   20.30 -be loaded as an HVM domain, and booted using an emulated BIOS.
   20.31 -
   20.32 -When paravirtual booting is in use, the PV/bootloader field indicates the
   20.33 -bootloader to use.  It may be "pygrub", in which case the platform's
   20.34 -default installation of pygrub will be used, or a full path within the
   20.35 -control domain to some other bootloader.  The other fields, PV/kernel,
   20.36 -PV/ramdisk, PV/args and PV/bootloader\_args will be passed to the
   20.37 -bootloader unmodified, and interpretation of those fields is then specific
   20.38 -to the bootloader itself, including the possibility that the bootloader
   20.39 -will ignore some or all of those given values. Finally the paths of all
   20.40 -bootable disks are added to the bootloader commandline (a disk is bootable
   20.41 -if its VBD has the bootable flag set). There may be zero, one or many
   20.42 -bootable disks; the bootloader decides which disk (if any) to boot from.
   20.43 -
   20.44 -If the bootloader is pygrub, then the menu.lst is parsed if present in the
   20.45 -guest's filesystem, otherwise the specified kernel and ramdisk are used, or
   20.46 -an autodetected kernel is used if nothing is specified and autodetection is
   20.47 -possible.  PV/args is appended to the kernel command line, no matter which
   20.48 -mechanism is used for finding the kernel.
   20.49 -
   20.50 -If PV/bootloader is empty but PV/kernel is specified, then the kernel and
   20.51 -ramdisk values will be treated as paths within the control domain.  If both
   20.52 -PV/bootloader and PV/kernel are empty, then the behaviour is as if
   20.53 -PV/bootloader was specified as "pygrub".
   20.54 -
   20.55 -When using HVM booting, HVM/boot\_policy and HVM/boot\_params specify the
   20.56 -boot handling.  Only one policy is currently defined: "BIOS order".  In
   20.57 -this case, HVM/boot\_params should contain one key-value pair "order" = "N"
   20.58 -where N is the string that will be passed to QEMU.}} \\
   20.59 +virtual machine (or 'guest').}} \\
   20.60  \hline
   20.61  Quals & Field & Type & Description \\
   20.62  \hline
   20.63 @@ -1072,7 +1039,6 @@ Quals & Field & Type & Description \\
   20.64  $\mathit{RW}$ &  {\tt memory/dynamic\_max} & int & Dynamic maximum (bytes) \\
   20.65  $\mathit{RW}$ &  {\tt memory/dynamic\_min} & int & Dynamic minimum (bytes) \\
   20.66  $\mathit{RW}$ &  {\tt memory/static\_min} & int & Statically-set (i.e. absolute) mininum (bytes) \\
   20.67 -$\mathit{RW}$ &  {\tt VCPUs/policy} & string & the name of the VCPU scheduling policy to be applied \\
   20.68  $\mathit{RW}$ &  {\tt VCPUs/params} & (string $\rightarrow$ string) Map & configuration parameters for the selected VCPU policy \\
   20.69  $\mathit{RW}$ &  {\tt VCPUs/max} & int & Max number of VCPUs \\
   20.70  $\mathit{RW}$ &  {\tt VCPUs/at\_startup} & int & Boot number of VCPUs \\
   20.71 @@ -1091,12 +1057,8 @@ Quals & Field & Type & Description \\
   20.72  $\mathit{RW}$ &  {\tt PV/bootloader\_args} & string & miscellaneous arguments for the bootloader \\
   20.73  $\mathit{RW}$ &  {\tt HVM/boot\_policy} & string & HVM boot policy \\
   20.74  $\mathit{RW}$ &  {\tt HVM/boot\_params} & (string $\rightarrow$ string) Map & HVM boot params \\
   20.75 -$\mathit{RW}$ &  {\tt platform/std\_VGA} & bool & emulate standard VGA instead of cirrus logic \\
   20.76 -$\mathit{RW}$ &  {\tt platform/serial} & string & redirect serial port to pty \\
   20.77 -$\mathit{RW}$ &  {\tt platform/localtime} & bool & set RTC to local time \\
   20.78 -$\mathit{RW}$ &  {\tt platform/clock\_offset} & bool & timeshift applied to guest's clock \\
   20.79 -$\mathit{RW}$ &  {\tt platform/enable\_audio} & bool & emulate audio \\
   20.80 -$\mathit{RO}_\mathit{ins}$ &  {\tt PCI\_bus} & string & PCI bus path for pass-through devices \\
   20.81 +$\mathit{RW}$ &  {\tt platform} & (string $\rightarrow$ string) Map & platform-specific configuration \\
   20.82 +$\mathit{RW}$ &  {\tt PCI\_bus} & string & PCI bus path for pass-through devices \\
   20.83  $\mathit{RW}$ &  {\tt other\_config} & (string $\rightarrow$ string) Map & additional configuration \\
   20.84  $\mathit{RO}_\mathit{run}$ &  {\tt domid} & int & domain ID (if available, -1 otherwise) \\
   20.85  $\mathit{RO}_\mathit{run}$ &  {\tt is\_control\_domain} & bool & true if this is a control domain (domain 0 or a driver domain) \\
   20.86 @@ -1104,7 +1066,7 @@ Quals & Field & Type & Description \\
   20.87  $\mathit{RO}_\mathit{run}$ &  {\tt guest\_metrics} & VM\_guest\_metrics ref & metrics associated with the running guest \\
   20.88  \hline
   20.89  \end{longtable}
   20.90 -\subsection{Additional RPCs associated with class: VM}
   20.91 +\subsection{RPCs associated with class: VM}
   20.92  \subsubsection{RPC name:~clone}
   20.93  
   20.94  {\bf Overview:} 
   20.95 @@ -1178,7 +1140,8 @@ void
   20.96  
   20.97  \vspace{0.3cm}
   20.98  
   20.99 -\noindent{\bf Possible Error Codes:} {\tt VM\_BAD\_POWER\_STATE}
  20.100 +\noindent{\bf Possible Error Codes:} {\tt VM\_BAD\_POWER\_STATE}, {\tt
  20.101 +VM\_HVM\_REQUIRED}
  20.102  
  20.103  \vspace{0.6cm}
  20.104  \subsubsection{RPC name:~pause}
  20.105 @@ -1362,8 +1325,10 @@ void
  20.106  
  20.107  
  20.108  \vspace{0.3cm}
  20.109 -\vspace{0.3cm}
  20.110 -\vspace{0.3cm}
  20.111 +
  20.112 +\noindent{\bf Possible Error Codes:} {\tt VM\_BAD\_POWER\_STATE}
  20.113 +
  20.114 +\vspace{0.6cm}
  20.115  \subsubsection{RPC name:~hard\_reboot}
  20.116  
  20.117  {\bf Overview:} 
  20.118 @@ -2212,72 +2177,6 @@ void
  20.119  \vspace{0.3cm}
  20.120  \vspace{0.3cm}
  20.121  \vspace{0.3cm}
  20.122 -\subsubsection{RPC name:~get\_VCPUs\_policy}
  20.123 -
  20.124 -{\bf Overview:} 
  20.125 -Get the VCPUs/policy field of the given VM.
  20.126 -
  20.127 - \noindent {\bf Signature:} 
  20.128 -\begin{verbatim} string get_VCPUs_policy (session_id s, VM ref self)\end{verbatim}
  20.129 -
  20.130 -
  20.131 -\noindent{\bf Arguments:}
  20.132 -
  20.133 - 
  20.134 -\vspace{0.3cm}
  20.135 -\begin{tabular}{|c|c|p{7cm}|}
  20.136 - \hline
  20.137 -{\bf type} & {\bf name} & {\bf description} \\ \hline
  20.138 -{\tt VM ref } & self & reference to the object \\ \hline 
  20.139 -
  20.140 -\end{tabular}
  20.141 -
  20.142 -\vspace{0.3cm}
  20.143 -
  20.144 - \noindent {\bf Return Type:} 
  20.145 -{\tt 
  20.146 -string
  20.147 -}
  20.148 -
  20.149 -
  20.150 -value of the field
  20.151 -\vspace{0.3cm}
  20.152 -\vspace{0.3cm}
  20.153 -\vspace{0.3cm}
  20.154 -\subsubsection{RPC name:~set\_VCPUs\_policy}
  20.155 -
  20.156 -{\bf Overview:} 
  20.157 -Set the VCPUs/policy field of the given VM.
  20.158 -
  20.159 - \noindent {\bf Signature:} 
  20.160 -\begin{verbatim} void set_VCPUs_policy (session_id s, VM ref self, string value)\end{verbatim}
  20.161 -
  20.162 -
  20.163 -\noindent{\bf Arguments:}
  20.164 -
  20.165 - 
  20.166 -\vspace{0.3cm}
  20.167 -\begin{tabular}{|c|c|p{7cm}|}
  20.168 - \hline
  20.169 -{\bf type} & {\bf name} & {\bf description} \\ \hline
  20.170 -{\tt VM ref } & self & reference to the object \\ \hline 
  20.171 -
  20.172 -{\tt string } & value & New value to set \\ \hline 
  20.173 -
  20.174 -\end{tabular}
  20.175 -
  20.176 -\vspace{0.3cm}
  20.177 -
  20.178 - \noindent {\bf Return Type:} 
  20.179 -{\tt 
  20.180 -void
  20.181 -}
  20.182 -
  20.183 -
  20.184 -
  20.185 -\vspace{0.3cm}
  20.186 -\vspace{0.3cm}
  20.187 -\vspace{0.3cm}
  20.188  \subsubsection{RPC name:~get\_VCPUs\_params}
  20.189  
  20.190  {\bf Overview:} 
  20.191 @@ -3438,45 +3337,13 @@ void
  20.192  \vspace{0.3cm}
  20.193  \vspace{0.3cm}
  20.194  \vspace{0.3cm}
  20.195 -\subsubsection{RPC name:~get\_platform\_std\_VGA}
  20.196 -
  20.197 -{\bf Overview:} 
  20.198 -Get the platform/std\_VGA field of the given VM.
  20.199 -
  20.200 - \noindent {\bf Signature:} 
  20.201 -\begin{verbatim} bool get_platform_std_VGA (session_id s, VM ref self)\end{verbatim}
  20.202 -
  20.203 -
  20.204 -\noindent{\bf Arguments:}
  20.205 -
  20.206 - 
  20.207 -\vspace{0.3cm}
  20.208 -\begin{tabular}{|c|c|p{7cm}|}
  20.209 - \hline
  20.210 -{\bf type} & {\bf name} & {\bf description} \\ \hline
  20.211 -{\tt VM ref } & self & reference to the object \\ \hline 
  20.212 -
  20.213 -\end{tabular}
  20.214 -
  20.215 -\vspace{0.3cm}
  20.216 -
  20.217 - \noindent {\bf Return Type:} 
  20.218 -{\tt 
  20.219 -bool
  20.220 -}
  20.221 -
  20.222 -
  20.223 -value of the field
  20.224 -\vspace{0.3cm}
  20.225 -\vspace{0.3cm}
  20.226 -\vspace{0.3cm}
  20.227 -\subsubsection{RPC name:~set\_platform\_std\_VGA}
  20.228 -
  20.229 -{\bf Overview:} 
  20.230 -Set the platform/std\_VGA field of the given VM.
  20.231 -
  20.232 - \noindent {\bf Signature:} 
  20.233 -\begin{verbatim} void set_platform_std_VGA (session_id s, VM ref self, bool value)\end{verbatim}
  20.234 +\subsubsection{RPC name:~get\_platform}
  20.235 +
  20.236 +{\bf Overview:} 
  20.237 +Get the platform field of the given VM.
  20.238 +
  20.239 + \noindent {\bf Signature:} 
  20.240 +\begin{verbatim} ((string -> string) Map) get_platform (session_id s, VM ref self)\end{verbatim}
  20.241  
  20.242  
  20.243  \noindent{\bf Arguments:}
  20.244 @@ -3488,95 +3355,27 @@ Set the platform/std\_VGA field of the g
  20.245  {\bf type} & {\bf name} & {\bf description} \\ \hline
  20.246  {\tt VM ref } & self & reference to the object \\ \hline 
  20.247  
  20.248 -{\tt bool } & value & New value to set \\ \hline 
  20.249 -
  20.250 -\end{tabular}
  20.251 -
  20.252 -\vspace{0.3cm}
  20.253 -
  20.254 - \noindent {\bf Return Type:} 
  20.255 -{\tt 
  20.256 -void
  20.257 -}
  20.258 -
  20.259 -
  20.260 -
  20.261 -\vspace{0.3cm}
  20.262 -\vspace{0.3cm}
  20.263 -\vspace{0.3cm}
  20.264 -\subsubsection{RPC name:~get\_platform\_serial}
  20.265 -
  20.266 -{\bf Overview:} 
  20.267 -Get the platform/serial field of the given VM.
  20.268 -
  20.269 - \noindent {\bf Signature:} 
  20.270 -\begin{verbatim} string get_platform_serial (session_id s, VM ref self)\end{verbatim}
  20.271 -
  20.272 -
  20.273 -\noindent{\bf Arguments:}
  20.274 -
  20.275 - 
  20.276 -\vspace{0.3cm}
  20.277 -\begin{tabular}{|c|c|p{7cm}|}
  20.278 - \hline
  20.279 -{\bf type} & {\bf name} & {\bf description} \\ \hline
  20.280 -{\tt VM ref } & self & reference to the object \\ \hline 
  20.281 -
  20.282 -\end{tabular}
  20.283 -
  20.284 -\vspace{0.3cm}
  20.285 -
  20.286 - \noindent {\bf Return Type:} 
  20.287 -{\tt 
  20.288 -string
  20.289 -}
  20.290 -
  20.291 -
  20.292 -value of the field
  20.293 -\vspace{0.3cm}
  20.294 -\vspace{0.3cm}
  20.295 -\vspace{0.3cm}
  20.296 -\subsubsection{RPC name:~set\_platform\_serial}
  20.297 -
  20.298 -{\bf Overview:} 
  20.299 -Set the platform/serial field of the given VM.
  20.300 -
  20.301 - \noindent {\bf Signature:} 
  20.302 -\begin{verbatim} void set_platform_serial (session_id s, VM ref self, string value)\end{verbatim}
  20.303 -
  20.304 -
  20.305 -\noindent{\bf Arguments:}
  20.306 -
  20.307 - 
  20.308 -\vspace{0.3cm}
  20.309 -\begin{tabular}{|c|c|p{7cm}|}
  20.310 - \hline
  20.311 -{\bf type} & {\bf name} & {\bf description} \\ \hline
  20.312 -{\tt VM ref } & self & reference to the object \\ \hline 
  20.313 -
  20.314 -{\tt string } & value & New value to set \\ \hline 
  20.315 -
  20.316 -\end{tabular}
  20.317 -
  20.318 -\vspace{0.3cm}
  20.319 -
  20.320 - \noindent {\bf Return Type:} 
  20.321 -{\tt 
  20.322 -void
  20.323 -}
  20.324 -
  20.325 -
  20.326 -
  20.327 -\vspace{0.3cm}
  20.328 -\vspace{0.3cm}
  20.329 -\vspace{0.3cm}
  20.330 -\subsubsection{RPC name:~get\_platform\_localtime}
  20.331 -
  20.332 -{\bf Overview:} 
  20.333 -Get the platform/localtime field of the given VM.
  20.334 -
  20.335 - \noindent {\bf Signature:} 
  20.336 -\begin{verbatim} bool get_platform_localtime (session_id s, VM ref self)\end{verbatim}
  20.337 +\end{tabular}
  20.338 +
  20.339 +\vspace{0.3cm}
  20.340 +
  20.341 + \noindent {\bf Return Type:} 
  20.342 +{\tt 
  20.343 +(string $\rightarrow$ string) Map
  20.344 +}
  20.345 +
  20.346 +
  20.347 +value of the field
  20.348 +\vspace{0.3cm}
  20.349 +\vspace{0.3cm}
  20.350 +\vspace{0.3cm}
  20.351 +\subsubsection{RPC name:~set\_platform}
  20.352 +
  20.353 +{\bf Overview:} 
  20.354 +Set the platform field of the given VM.
  20.355 +
  20.356 + \noindent {\bf Signature:} 
  20.357 +\begin{verbatim} void set_platform (session_id s, VM ref self, (string -> string) Map value)\end{verbatim}
  20.358  
  20.359  
  20.360  \noindent{\bf Arguments:}
  20.361 @@ -3588,61 +3387,29 @@ Get the platform/localtime field of the 
  20.362  {\bf type} & {\bf name} & {\bf description} \\ \hline
  20.363  {\tt VM ref } & self & reference to the object \\ \hline 
  20.364  
  20.365 -\end{tabular}
  20.366 -
  20.367 -\vspace{0.3cm}
  20.368 -
  20.369 - \noindent {\bf Return Type:} 
  20.370 -{\tt 
  20.371 -bool
  20.372 -}
  20.373 -
  20.374 -
  20.375 -value of the field
  20.376 -\vspace{0.3cm}
  20.377 -\vspace{0.3cm}
  20.378 -\vspace{0.3cm}
  20.379 -\subsubsection{RPC name:~set\_platform\_localtime}
  20.380 -
  20.381 -{\bf Overview:} 
  20.382 -Set the platform/localtime field of the given VM.
  20.383 -
  20.384 - \noindent {\bf Signature:} 
  20.385 -\begin{verbatim} void set_platform_localtime (session_id s, VM ref self, bool value)\end{verbatim}
  20.386 -
  20.387 -
  20.388 -\noindent{\bf Arguments:}
  20.389 -
  20.390 - 
  20.391 -\vspace{0.3cm}
  20.392 -\begin{tabular}{|c|c|p{7cm}|}
  20.393 - \hline
  20.394 -{\bf type} & {\bf name} & {\bf description} \\ \hline
  20.395 -{\tt VM ref } & self & reference to the object \\ \hline 
  20.396 -
  20.397 -{\tt bool } & value & New value to set \\ \hline 
  20.398 -
  20.399 -\end{tabular}
  20.400 -
  20.401 -\vspace{0.3cm}
  20.402 -
  20.403 - \noindent {\bf Return Type:} 
  20.404 -{\tt 
  20.405 -void
  20.406 -}
  20.407 -
  20.408 -
  20.409 -
  20.410 -\vspace{0.3cm}
  20.411 -\vspace{0.3cm}
  20.412 -\vspace{0.3cm}
  20.413 -\subsubsection{RPC name:~get\_platform\_clock\_offset}
  20.414 -
  20.415 -{\bf Overview:} 
  20.416 -Get the platform/clock\_offset field of the given VM.
  20.417 -
  20.418 - \noindent {\bf Signature:} 
  20.419 -\begin{verbatim} bool get_platform_clock_offset (session_id s, VM ref self)\end{verbatim}
  20.420 +{\tt (string $\rightarrow$ string) Map } & value & New value to set \\ \hline 
  20.421 +
  20.422 +\end{tabular}
  20.423 +
  20.424 +\vspace{0.3cm}
  20.425 +
  20.426 + \noindent {\bf Return Type:} 
  20.427 +{\tt 
  20.428 +void
  20.429 +}
  20.430 +
  20.431 +
  20.432 +
  20.433 +\vspace{0.3cm}
  20.434 +\vspace{0.3cm}
  20.435 +\vspace{0.3cm}
  20.436 +\subsubsection{RPC name:~add\_to\_platform}
  20.437 +
  20.438 +{\bf Overview:} 
  20.439 +Add the given key-value pair to the platform field of the given VM.
  20.440 +
  20.441 + \noindent {\bf Signature:} 
  20.442 +\begin{verbatim} void add_to_platform (session_id s, VM ref self, string key, string value)\end{verbatim}
  20.443  
  20.444  
  20.445  \noindent{\bf Arguments:}
  20.446 @@ -3654,27 +3421,32 @@ Get the platform/clock\_offset field of 
  20.447  {\bf type} & {\bf name} & {\bf description} \\ \hline
  20.448  {\tt VM ref } & self & reference to the object \\ \hline 
  20.449  
  20.450 -\end{tabular}
  20.451 -
  20.452 -\vspace{0.3cm}
  20.453 -
  20.454 - \noindent {\bf Return Type:} 
  20.455 -{\tt 
  20.456 -bool
  20.457 -}
  20.458 -
  20.459 -
  20.460 -value of the field
  20.461 -\vspace{0.3cm}
  20.462 -\vspace{0.3cm}
  20.463 -\vspace{0.3cm}
  20.464 -\subsubsection{RPC name:~set\_platform\_clock\_offset}
  20.465 -
  20.466 -{\bf Overview:} 
  20.467 -Set the platform/clock\_offset field of the given VM.
  20.468 -
  20.469 - \noindent {\bf Signature:} 
  20.470 -\begin{verbatim} void set_platform_clock_offset (session_id s, VM ref self, bool value)\end{verbatim}
  20.471 +{\tt string } & key & Key to add \\ \hline 
  20.472 +
  20.473 +{\tt string } & value & Value to add \\ \hline 
  20.474 +
  20.475 +\end{tabular}
  20.476 +
  20.477 +\vspace{0.3cm}
  20.478 +
  20.479 + \noindent {\bf Return Type:} 
  20.480 +{\tt 
  20.481 +void
  20.482 +}
  20.483 +
  20.484 +
  20.485 +
  20.486 +\vspace{0.3cm}
  20.487 +\vspace{0.3cm}
  20.488 +\vspace{0.3cm}
  20.489 +\subsubsection{RPC name:~remove\_from\_platform}
  20.490 +
  20.491 +{\bf Overview:} 
  20.492 +Remove the given key and its corresponding value from the platform field of
  20.493 +the given VM.  If the key is not in that Map, then do nothing.
  20.494 +
  20.495 + \noindent {\bf Signature:} 
  20.496 +\begin{verbatim} void remove_from_platform (session_id s, VM ref self, string key)\end{verbatim}
  20.497  
  20.498  
  20.499  \noindent{\bf Arguments:}
  20.500 @@ -3686,73 +3458,7 @@ Set the platform/clock\_offset field of 
  20.501  {\bf type} & {\bf name} & {\bf description} \\ \hline
  20.502  {\tt VM ref } & self & reference to the object \\ \hline 
  20.503  
  20.504 -{\tt bool } & value & New value to set \\ \hline 
  20.505 -
  20.506 -\end{tabular}
  20.507 -
  20.508 -\vspace{0.3cm}
  20.509 -
  20.510 - \noindent {\bf Return Type:} 
  20.511 -{\tt 
  20.512 -void
  20.513 -}
  20.514 -
  20.515 -
  20.516 -
  20.517 -\vspace{0.3cm}
  20.518 -\vspace{0.3cm}
  20.519 -\vspace{0.3cm}
  20.520 -\subsubsection{RPC name:~get\_platform\_enable\_audio}
  20.521 -
  20.522 -{\bf Overview:} 
  20.523 -Get the platform/enable\_audio field of the given VM.
  20.524 -
  20.525 - \noindent {\bf Signature:} 
  20.526 -\begin{verbatim} bool get_platform_enable_audio (session_id s, VM ref self)\end{verbatim}
  20.527 -
  20.528 -
  20.529 -\noindent{\bf Arguments:}
  20.530 -
  20.531 - 
  20.532 -\vspace{0.3cm}
  20.533 -\begin{tabular}{|c|c|p{7cm}|}
  20.534 - \hline
  20.535 -{\bf type} & {\bf name} & {\bf description} \\ \hline
  20.536 -{\tt VM ref } & self & reference to the object \\ \hline 
  20.537 -
  20.538 -\end{tabular}
  20.539 -
  20.540 -\vspace{0.3cm}
  20.541 -
  20.542 - \noindent {\bf Return Type:} 
  20.543 -{\tt 
  20.544 -bool
  20.545 -}
  20.546 -
  20.547 -
  20.548 -value of the field
  20.549 -\vspace{0.3cm}
  20.550 -\vspace{0.3cm}
  20.551 -\vspace{0.3cm}
  20.552 -\subsubsection{RPC name:~set\_platform\_enable\_audio}
  20.553 -
  20.554 -{\bf Overview:} 
  20.555 -Set the platform/enable\_audio field of the given VM.
  20.556 -
  20.557 - \noindent {\bf Signature:} 
  20.558 -\begin{verbatim} void set_platform_enable_audio (session_id s, VM ref self, bool value)\end{verbatim}
  20.559 -
  20.560 -
  20.561 -\noindent{\bf Arguments:}
  20.562 -
  20.563 - 
  20.564 -\vspace{0.3cm}
  20.565 -\begin{tabular}{|c|c|p{7cm}|}
  20.566 - \hline
  20.567 -{\bf type} & {\bf name} & {\bf description} \\ \hline
  20.568 -{\tt VM ref } & self & reference to the object \\ \hline 
  20.569 -
  20.570 -{\tt bool } & value & New value to set \\ \hline 
  20.571 +{\tt string } & key & Key to remove \\ \hline 
  20.572  
  20.573  \end{tabular}
  20.574  
  20.575 @@ -3800,6 +3506,40 @@ value of the field
  20.576  \vspace{0.3cm}
  20.577  \vspace{0.3cm}
  20.578  \vspace{0.3cm}
  20.579 +\subsubsection{RPC name:~set\_PCI\_bus}
  20.580 +
  20.581 +{\bf Overview:} 
  20.582 +Set the PCI\_bus field of the given VM.
  20.583 +
  20.584 + \noindent {\bf Signature:} 
  20.585 +\begin{verbatim} void set_PCI_bus (session_id s, VM ref self, string value)\end{verbatim}
  20.586 +
  20.587 +
  20.588 +\noindent{\bf Arguments:}
  20.589 +
  20.590 + 
  20.591 +\vspace{0.3cm}
  20.592 +\begin{tabular}{|c|c|p{7cm}|}
  20.593 + \hline
  20.594 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  20.595 +{\tt VM ref } & self & reference to the object \\ \hline 
  20.596 +
  20.597 +{\tt string } & value & New value to set \\ \hline 
  20.598 +
  20.599 +\end{tabular}
  20.600 +
  20.601 +\vspace{0.3cm}
  20.602 +
  20.603 + \noindent {\bf Return Type:} 
  20.604 +{\tt 
  20.605 +void
  20.606 +}
  20.607 +
  20.608 +
  20.609 +
  20.610 +\vspace{0.3cm}
  20.611 +\vspace{0.3cm}
  20.612 +\vspace{0.3cm}
  20.613  \subsubsection{RPC name:~get\_other\_config}
  20.614  
  20.615  {\bf Overview:} 
  20.616 @@ -4245,7 +3985,7 @@ Quals & Field & Type & Description \\
  20.617  $\mathit{RO}_\mathit{run}$ &  {\tt VCPUs/utilisation} & (int $\rightarrow$ float) Map & Utilisation for all of guest's current VCPUs \\
  20.618  \hline
  20.619  \end{longtable}
  20.620 -\subsection{Additional RPCs associated with class: VM\_metrics}
  20.621 +\subsection{RPCs associated with class: VM\_metrics}
  20.622  \subsubsection{RPC name:~get\_all}
  20.623  
  20.624  {\bf Overview:} 
  20.625 @@ -4481,7 +4221,7 @@ Quals & Field & Type & Description \\
  20.626  $\mathit{RO}_\mathit{run}$ &  {\tt other} & (string $\rightarrow$ string) Map & anything else \\
  20.627  \hline
  20.628  \end{longtable}
  20.629 -\subsection{Additional RPCs associated with class: VM\_guest\_metrics}
  20.630 +\subsection{RPCs associated with class: VM\_guest\_metrics}
  20.631  \subsubsection{RPC name:~get\_all}
  20.632  
  20.633  {\bf Overview:} 
  20.634 @@ -4825,7 +4565,7 @@ Quals & Field & Type & Description \\
  20.635  $\mathit{RO}_\mathit{ins}$ &  {\tt metrics} & host\_metrics ref & metrics associated with this host. \\
  20.636  \hline
  20.637  \end{longtable}
  20.638 -\subsection{Additional RPCs associated with class: host}
  20.639 +\subsection{RPCs associated with class: host}
  20.640  \subsubsection{RPC name:~disable}
  20.641  
  20.642  {\bf Overview:} 
  20.643 @@ -6078,7 +5818,7 @@ Quals & Field & Type & Description \\
  20.644  $\mathit{RO}_\mathit{run}$ &  {\tt memory/free} & int & Host's free memory (bytes) \\
  20.645  \hline
  20.646  \end{longtable}
  20.647 -\subsection{Additional RPCs associated with class: host\_metrics}
  20.648 +\subsection{RPCs associated with class: host\_metrics}
  20.649  \subsubsection{RPC name:~get\_all}
  20.650  
  20.651  {\bf Overview:} 
  20.652 @@ -6283,7 +6023,7 @@ Quals & Field & Type & Description \\
  20.653  $\mathit{RO}_\mathit{run}$ &  {\tt utilisation} & float & the current CPU utilisation \\
  20.654  \hline
  20.655  \end{longtable}
  20.656 -\subsection{Additional RPCs associated with class: host\_cpu}
  20.657 +\subsection{RPCs associated with class: host\_cpu}
  20.658  \subsubsection{RPC name:~get\_all}
  20.659  
  20.660  {\bf Overview:} 
  20.661 @@ -6677,7 +6417,7 @@ Quals & Field & Type & Description \\
  20.662  $\mathit{RO}_\mathit{run}$ &  {\tt PIFs} & (PIF ref) Set & list of connected pifs \\
  20.663  \hline
  20.664  \end{longtable}
  20.665 -\subsection{Additional RPCs associated with class: network}
  20.666 +\subsection{RPCs associated with class: network}
  20.667  \subsubsection{RPC name:~get\_all}
  20.668  
  20.669  {\bf Overview:} 
  20.670 @@ -7115,7 +6855,72 @@ Quals & Field & Type & Description \\
  20.671  $\mathit{RO}_\mathit{run}$ &  {\tt metrics} & VIF\_metrics ref & metrics associated with this VIF. \\
  20.672  \hline
  20.673  \end{longtable}
  20.674 -\subsection{Additional RPCs associated with class: VIF}
  20.675 +\subsection{RPCs associated with class: VIF}
  20.676 +\subsubsection{RPC name:~plug}
  20.677 +
  20.678 +{\bf Overview:} 
  20.679 +Hotplug the specified VIF, dynamically attaching it to the running VM.
  20.680 +
  20.681 + \noindent {\bf Signature:} 
  20.682 +\begin{verbatim} void plug (session_id s, VIF ref self)\end{verbatim}
  20.683 +
  20.684 +
  20.685 +\noindent{\bf Arguments:}
  20.686 +
  20.687 + 
  20.688 +\vspace{0.3cm}
  20.689 +\begin{tabular}{|c|c|p{7cm}|}
  20.690 + \hline
  20.691 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  20.692 +{\tt VIF ref } & self & The VIF to hotplug \\ \hline 
  20.693 +
  20.694 +\end{tabular}
  20.695 +
  20.696 +\vspace{0.3cm}
  20.697 +
  20.698 + \noindent {\bf Return Type:} 
  20.699 +{\tt 
  20.700 +void
  20.701 +}
  20.702 +
  20.703 +
  20.704 +
  20.705 +\vspace{0.3cm}
  20.706 +\vspace{0.3cm}
  20.707 +\vspace{0.3cm}
  20.708 +\subsubsection{RPC name:~unplug}
  20.709 +
  20.710 +{\bf Overview:} 
  20.711 +Hot-unplug the specified VIF, dynamically unattaching it from the running
  20.712 +VM.
  20.713 +
  20.714 + \noindent {\bf Signature:} 
  20.715 +\begin{verbatim} void unplug (session_id s, VIF ref self)\end{verbatim}
  20.716 +
  20.717 +
  20.718 +\noindent{\bf Arguments:}
  20.719 +
  20.720 + 
  20.721 +\vspace{0.3cm}
  20.722 +\begin{tabular}{|c|c|p{7cm}|}
  20.723 + \hline
  20.724 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  20.725 +{\tt VIF ref } & self & The VIF to hot-unplug \\ \hline 
  20.726 +
  20.727 +\end{tabular}
  20.728 +
  20.729 +\vspace{0.3cm}
  20.730 +
  20.731 + \noindent {\bf Return Type:} 
  20.732 +{\tt 
  20.733 +void
  20.734 +}
  20.735 +
  20.736 +
  20.737 +
  20.738 +\vspace{0.3cm}
  20.739 +\vspace{0.3cm}
  20.740 +\vspace{0.3cm}
  20.741  \subsubsection{RPC name:~get\_all}
  20.742  
  20.743  {\bf Overview:} 
  20.744 @@ -7942,7 +7747,7 @@ Quals & Field & Type & Description \\
  20.745  $\mathit{RO}_\mathit{run}$ &  {\tt io/write\_kbs} & float & Write bandwidth (KiB/s) \\
  20.746  \hline
  20.747  \end{longtable}
  20.748 -\subsection{Additional RPCs associated with class: VIF\_metrics}
  20.749 +\subsection{RPCs associated with class: VIF\_metrics}
  20.750  \subsubsection{RPC name:~get\_all}
  20.751  
  20.752  {\bf Overview:} 
  20.753 @@ -8148,7 +7953,7 @@ Quals & Field & Type & Description \\
  20.754  $\mathit{RO}_\mathit{ins}$ &  {\tt metrics} & PIF\_metrics ref & metrics associated with this PIF. \\
  20.755  \hline
  20.756  \end{longtable}
  20.757 -\subsection{Additional RPCs associated with class: PIF}
  20.758 +\subsection{RPCs associated with class: PIF}
  20.759  \subsubsection{RPC name:~create\_VLAN}
  20.760  
  20.761  {\bf Overview:} 
  20.762 @@ -8719,7 +8524,7 @@ Quals & Field & Type & Description \\
  20.763  $\mathit{RO}_\mathit{run}$ &  {\tt io/write\_kbs} & float & Write bandwidth (KiB/s) \\
  20.764  \hline
  20.765  \end{longtable}
  20.766 -\subsection{Additional RPCs associated with class: PIF\_metrics}
  20.767 +\subsection{RPCs associated with class: PIF\_metrics}
  20.768  \subsubsection{RPC name:~get\_all}
  20.769  
  20.770  {\bf Overview:} 
  20.771 @@ -8926,7 +8731,7 @@ Quals & Field & Type & Description \\
  20.772  $\mathit{RO}_\mathit{ins}$ &  {\tt location} & string & a string that uniquely determines the location of the storage repository; the format of this string depends on the repository's type \\
  20.773  \hline
  20.774  \end{longtable}
  20.775 -\subsection{Additional RPCs associated with class: SR}
  20.776 +\subsection{RPCs associated with class: SR}
  20.777  \subsubsection{RPC name:~clone}
  20.778  
  20.779  {\bf Overview:} 
  20.780 @@ -9549,18 +9354,18 @@ Quals & Field & Type & Description \\
  20.781  $\mathit{RO}_\mathit{run}$ &  {\tt uuid} & string & unique identifier/object reference \\
  20.782  $\mathit{RW}$ &  {\tt name/label} & string & a human-readable name \\
  20.783  $\mathit{RW}$ &  {\tt name/description} & string & a notes field containg human-readable description \\
  20.784 -$\mathit{RW}$ &  {\tt SR} & SR ref & storage repository in which the VDI resides \\
  20.785 +$\mathit{RO}_\mathit{ins}$ &  {\tt SR} & SR ref & storage repository in which the VDI resides \\
  20.786  $\mathit{RO}_\mathit{run}$ &  {\tt VBDs} & (VBD ref) Set & list of vbds that refer to this disk \\
  20.787  $\mathit{RO}_\mathit{run}$ &  {\tt crash\_dumps} & (crashdump ref) Set & list of crash dumps that refer to this disk \\
  20.788  $\mathit{RW}$ &  {\tt virtual\_size} & int & size of disk as presented to the guest (in bytes). Note that, depending on storage backend type, requested size may not be respected exactly \\
  20.789  $\mathit{RO}_\mathit{run}$ &  {\tt physical\_utilisation} & int & amount of physical space that the disk image is currently taking up on the storage repository (in bytes) \\
  20.790 -$\mathit{RO}_\mathit{ins}$ &  {\tt sector\_size} & int & sector size of VDI (in bytes) \\
  20.791  $\mathit{RO}_\mathit{ins}$ &  {\tt type} & vdi\_type & type of the VDI \\
  20.792  $\mathit{RW}$ &  {\tt sharable} & bool & true if this disk may be shared \\
  20.793  $\mathit{RW}$ &  {\tt read\_only} & bool & true if this disk may ONLY be mounted read-only \\
  20.794 +$\mathit{RW}$ &  {\tt other\_config} & (string $\rightarrow$ string) Map & additional configuration \\
  20.795  \hline
  20.796  \end{longtable}
  20.797 -\subsection{Additional RPCs associated with class: VDI}
  20.798 +\subsection{RPCs associated with class: VDI}
  20.799  \subsubsection{RPC name:~snapshot}
  20.800  
  20.801  {\bf Overview:} 
  20.802 @@ -9845,40 +9650,6 @@ value of the field
  20.803  \vspace{0.3cm}
  20.804  \vspace{0.3cm}
  20.805  \vspace{0.3cm}
  20.806 -\subsubsection{RPC name:~set\_SR}
  20.807 -
  20.808 -{\bf Overview:} 
  20.809 -Set the SR field of the given VDI.
  20.810 -
  20.811 - \noindent {\bf Signature:} 
  20.812 -\begin{verbatim} void set_SR (session_id s, VDI ref self, SR ref value)\end{verbatim}
  20.813 -
  20.814 -
  20.815 -\noindent{\bf Arguments:}
  20.816 -
  20.817 - 
  20.818 -\vspace{0.3cm}
  20.819 -\begin{tabular}{|c|c|p{7cm}|}
  20.820 - \hline
  20.821 -{\bf type} & {\bf name} & {\bf description} \\ \hline
  20.822 -{\tt VDI ref } & self & reference to the object \\ \hline 
  20.823 -
  20.824 -{\tt SR ref } & value & New value to set \\ \hline 
  20.825 -
  20.826 -\end{tabular}
  20.827 -
  20.828 -\vspace{0.3cm}
  20.829 -
  20.830 - \noindent {\bf Return Type:} 
  20.831 -{\tt 
  20.832 -void
  20.833 -}
  20.834 -
  20.835 -
  20.836 -
  20.837 -\vspace{0.3cm}
  20.838 -\vspace{0.3cm}
  20.839 -\vspace{0.3cm}
  20.840  \subsubsection{RPC name:~get\_VBDs}
  20.841  
  20.842  {\bf Overview:} 
  20.843 @@ -10041,38 +9812,6 @@ value of the field
  20.844  \vspace{0.3cm}
  20.845  \vspace{0.3cm}
  20.846  \vspace{0.3cm}
  20.847 -\subsubsection{RPC name:~get\_sector\_size}
  20.848 -
  20.849 -{\bf Overview:} 
  20.850 -Get the sector\_size field of the given VDI.
  20.851 -
  20.852 - \noindent {\bf Signature:} 
  20.853 -\begin{verbatim} int get_sector_size (session_id s, VDI ref self)\end{verbatim}
  20.854 -
  20.855 -
  20.856 -\noindent{\bf Arguments:}
  20.857 -
  20.858 - 
  20.859 -\vspace{0.3cm}
  20.860 -\begin{tabular}{|c|c|p{7cm}|}
  20.861 - \hline
  20.862 -{\bf type} & {\bf name} & {\bf description} \\ \hline
  20.863 -{\tt VDI ref } & self & reference to the object \\ \hline 
  20.864 -
  20.865 -\end{tabular}
  20.866 -
  20.867 -\vspace{0.3cm}
  20.868 -
  20.869 - \noindent {\bf Return Type:} 
  20.870 -{\tt 
  20.871 -int
  20.872 -}
  20.873 -
  20.874 -
  20.875 -value of the field
  20.876 -\vspace{0.3cm}
  20.877 -\vspace{0.3cm}
  20.878 -\vspace{0.3cm}
  20.879  \subsubsection{RPC name:~get\_type}
  20.880  
  20.881  {\bf Overview:} 
  20.882 @@ -10237,6 +9976,143 @@ void
  20.883  \vspace{0.3cm}
  20.884  \vspace{0.3cm}
  20.885  \vspace{0.3cm}
  20.886 +\subsubsection{RPC name:~get\_other\_config}
  20.887 +
  20.888 +{\bf Overview:} 
  20.889 +Get the other\_config field of the given VDI.
  20.890 +
  20.891 + \noindent {\bf Signature:} 
  20.892 +\begin{verbatim} ((string -> string) Map) get_other_config (session_id s, VDI ref self)\end{verbatim}
  20.893 +
  20.894 +
  20.895 +\noindent{\bf Arguments:}
  20.896 +
  20.897 + 
  20.898 +\vspace{0.3cm}
  20.899 +\begin{tabular}{|c|c|p{7cm}|}
  20.900 + \hline
  20.901 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  20.902 +{\tt VDI ref } & self & reference to the object \\ \hline 
  20.903 +
  20.904 +\end{tabular}
  20.905 +
  20.906 +\vspace{0.3cm}
  20.907 +
  20.908 + \noindent {\bf Return Type:} 
  20.909 +{\tt 
  20.910 +(string $\rightarrow$ string) Map
  20.911 +}
  20.912 +
  20.913 +
  20.914 +value of the field
  20.915 +\vspace{0.3cm}
  20.916 +\vspace{0.3cm}
  20.917 +\vspace{0.3cm}
  20.918 +\subsubsection{RPC name:~set\_other\_config}
  20.919 +
  20.920 +{\bf Overview:} 
  20.921 +Set the other\_config field of the given VDI.
  20.922 +
  20.923 + \noindent {\bf Signature:} 
  20.924 +\begin{verbatim} void set_other_config (session_id s, VDI ref self, (string -> string) Map value)\end{verbatim}
  20.925 +
  20.926 +
  20.927 +\noindent{\bf Arguments:}
  20.928 +
  20.929 + 
  20.930 +\vspace{0.3cm}
  20.931 +\begin{tabular}{|c|c|p{7cm}|}
  20.932 + \hline
  20.933 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  20.934 +{\tt VDI ref } & self & reference to the object \\ \hline 
  20.935 +
  20.936 +{\tt (string $\rightarrow$ string) Map } & value & New value to set \\ \hline 
  20.937 +
  20.938 +\end{tabular}
  20.939 +
  20.940 +\vspace{0.3cm}
  20.941 +
  20.942 + \noindent {\bf Return Type:} 
  20.943 +{\tt 
  20.944 +void
  20.945 +}
  20.946 +
  20.947 +
  20.948 +
  20.949 +\vspace{0.3cm}
  20.950 +\vspace{0.3cm}
  20.951 +\vspace{0.3cm}
  20.952 +\subsubsection{RPC name:~add\_to\_other\_config}
  20.953 +
  20.954 +{\bf Overview:} 
  20.955 +Add the given key-value pair to the other\_config field of the given VDI.
  20.956 +
  20.957 + \noindent {\bf Signature:} 
  20.958 +\begin{verbatim} void add_to_other_config (session_id s, VDI ref self, string key, string value)\end{verbatim}
  20.959 +
  20.960 +
  20.961 +\noindent{\bf Arguments:}
  20.962 +
  20.963 + 
  20.964 +\vspace{0.3cm}
  20.965 +\begin{tabular}{|c|c|p{7cm}|}
  20.966 + \hline
  20.967 +{\bf type} & {\bf name} & {\bf description} \\ \hline
  20.968 +{\tt VDI ref } & self & reference to the object \\ \hline 
  20.969 +
  20.970 +{\tt string } & key & Key to add \\ \hline 
  20.971 +
  20.972 +{\tt string } & value & Value to add \\ \hline 
  20.973 +
  20.974 +\end{tabular}
  20.975 +
  20.976 +\vspace{0.3cm}
  20.977 +
  20.978 + \noindent {\bf Return Type:} 
  20.979 +{\tt 
  20.980 +void
  20.981 +}
  20.982 +
  20.983 +
  20.984 +
  20.985 +\vspace{0.3cm}
  20.986 +\vspace{0.3cm}
  20.987 +\vspace{0.3cm}
  20.988 +\subsubsection{RPC name:~remove\_from\_other\_config}
  20.989 +
  20.990 +{\bf Overview:} 
  20.991 +Remove the given key and its corresponding value from the other\_config
  20.992 +field of the given VDI.  If the key is not in that Map, then do nothing.
  20.993 +
  20.994 + \noindent {\bf Signature:} 
  20.995 +\begin{verbatim} void remove_from_other_config (session_id s, VDI ref self, string key)\end{verbatim}
  20.996 +
  20.997 +
  20.998 +\noindent{\bf Arguments:}
  20.999 +
 20.1000 + 
 20.1001 +\vspace{0.3cm}
 20.1002 +\begin{tabular}{|c|c|p{7cm}|}
 20.1003 + \hline
 20.1004 +{\bf type} & {\bf name} & {\bf description} \\ \hline
 20.1005 +{\tt VDI ref } & self & reference to the object \\ \hline 
 20.1006 +
 20.1007 +{\tt string } & key & Key to remove \\ \hline 
 20.1008 +
 20.1009 +\end{tabular}
 20.1010 +
 20.1011 +\vspace{0.3cm}
 20.1012 +
 20.1013 + \noindent {\bf Return Type:} 
 20.1014 +{\tt 
 20.1015 +void
 20.1016 +}
 20.1017 +
 20.1018 +
 20.1019 +
 20.1020 +\vspace{0.3cm}
 20.1021 +\vspace{0.3cm}
 20.1022 +\vspace{0.3cm}
 20.1023  \subsubsection{RPC name:~create}
 20.1024  
 20.1025  {\bf Overview:} 
 20.1026 @@ -10426,7 +10302,7 @@ Quals & Field & Type & Description \\
 20.1027  $\mathit{RO}_\mathit{run}$ &  {\tt metrics} & VBD\_metrics ref & metrics associated with this VBD \\
 20.1028  \hline
 20.1029  \end{longtable}
 20.1030 -\subsection{Additional RPCs associated with class: VBD}
 20.1031 +\subsection{RPCs associated with class: VBD}
 20.1032  \subsubsection{RPC name:~media\_change}
 20.1033  
 20.1034  {\bf Overview:} 
 20.1035 @@ -10462,6 +10338,71 @@ void
 20.1036  \vspace{0.3cm}
 20.1037  \vspace{0.3cm}
 20.1038  \vspace{0.3cm}
 20.1039 +\subsubsection{RPC name:~plug}
 20.1040 +
 20.1041 +{\bf Overview:} 
 20.1042 +Hotplug the specified VBD, dynamically attaching it to the running VM.
 20.1043 +
 20.1044 + \noindent {\bf Signature:} 
 20.1045 +\begin{verbatim} void plug (session_id s, VBD ref self)\end{verbatim}
 20.1046 +
 20.1047 +
 20.1048 +\noindent{\bf Arguments:}
 20.1049 +
 20.1050 + 
 20.1051 +\vspace{0.3cm}
 20.1052 +\begin{tabular}{|c|c|p{7cm}|}
 20.1053 + \hline
 20.1054 +{\bf type} & {\bf name} & {\bf description} \\ \hline
 20.1055 +{\tt VBD ref } & self & The VBD to hotplug \\ \hline 
 20.1056 +
 20.1057 +\end{tabular}
 20.1058 +
 20.1059 +\vspace{0.3cm}
 20.1060 +
 20.1061 + \noindent {\bf Return Type:} 
 20.1062 +{\tt 
 20.1063 +void
 20.1064 +}
 20.1065 +
 20.1066 +
 20.1067 +
 20.1068 +\vspace{0.3cm}
 20.1069 +\vspace{0.3cm}
 20.1070 +\vspace{0.3cm}
 20.1071 +\subsubsection{RPC name:~unplug}
 20.1072 +
 20.1073 +{\bf Overview:} 
 20.1074 +Hot-unplug the specified VBD, dynamically unattaching it from the running
 20.1075 +VM.
 20.1076 +
 20.1077 + \noindent {\bf Signature:} 
 20.1078 +\begin{verbatim} void unplug (session_id s, VBD ref self)\end{verbatim}
 20.1079 +
 20.1080 +
 20.1081 +\noindent{\bf Arguments:}
 20.1082 +
 20.1083 + 
 20.1084 +\vspace{0.3cm}
 20.1085 +\begin{tabular}{|c|c|p{7cm}|}
 20.1086 + \hline
 20.1087 +{\bf type} & {\bf name} & {\bf description} \\ \hline
 20.1088 +{\tt VBD ref } & self & The VBD to hot-unplug \\ \hline 
 20.1089 +
 20.1090 +\end{tabular}
 20.1091 +
 20.1092 +\vspace{0.3cm}
 20.1093 +
 20.1094 + \noindent {\bf Return Type:} 
 20.1095 +{\tt 
 20.1096 +void
 20.1097 +}
 20.1098 +
 20.1099 +
 20.1100 +
 20.1101 +\vspace{0.3cm}
 20.1102 +\vspace{0.3cm}
 20.1103 +\vspace{0.3cm}
 20.1104  \subsubsection{RPC name:~get\_all}
 20.1105  
 20.1106  {\bf Overview:} 
 20.1107 @@ -11354,7 +11295,7 @@ Quals & Field & Type & Description \\
 20.1108  $\mathit{RO}_\mathit{run}$ &  {\tt io/write\_kbs} & float & Write bandwidth (KiB/s) \\
 20.1109  \hline
 20.1110  \end{longtable}
 20.1111 -\subsection{Additional RPCs associated with class: VBD\_metrics}
 20.1112 +\subsection{RPCs associated with class: VBD\_metrics}
 20.1113  \subsubsection{RPC name:~get\_all}
 20.1114  
 20.1115  {\bf Overview:} 
 20.1116 @@ -11556,7 +11497,7 @@ Quals & Field & Type & Description \\
 20.1117  $\mathit{RO}_\mathit{run}$ &  {\tt currently\_attached} & bool & is the SR currently attached on this host? \\
 20.1118  \hline
 20.1119  \end{longtable}
 20.1120 -\subsection{Additional RPCs associated with class: PBD}
 20.1121 +\subsection{RPCs associated with class: PBD}
 20.1122  \subsubsection{RPC name:~get\_all}
 20.1123  
 20.1124  {\bf Overview:} 
 20.1125 @@ -11884,7 +11825,39 @@ Quals & Field & Type & Description \\
 20.1126  $\mathit{RO}_\mathit{ins}$ &  {\tt VDI} & VDI ref & the virtual disk \\
 20.1127  \hline
 20.1128  \end{longtable}
 20.1129 -\subsection{Additional RPCs associated with class: crashdump}
 20.1130 +\subsection{RPCs associated with class: crashdump}
 20.1131 +\subsubsection{RPC name:~destroy}
 20.1132 +
 20.1133 +{\bf Overview:} 
 20.1134 +Destroy the specified crashdump.
 20.1135 +
 20.1136 + \noindent {\bf Signature:} 
 20.1137 +\begin{verbatim} void destroy (session_id s, crashdump ref self)\end{verbatim}
 20.1138 +
 20.1139 +
 20.1140 +\noindent{\bf Arguments:}
 20.1141 +
 20.1142 + 
 20.1143 +\vspace{0.3cm}
 20.1144 +\begin{tabular}{|c|c|p{7cm}|}
 20.1145 + \hline
 20.1146 +{\bf type} & {\bf name} & {\bf description} \\ \hline
 20.1147 +{\tt crashdump ref } & self & The crashdump to destroy \\ \hline 
 20.1148 +
 20.1149 +\end{tabular}
 20.1150 +
 20.1151 +\vspace{0.3cm}
 20.1152 +
 20.1153 + \noindent {\bf Return Type:} 
 20.1154 +{\tt 
 20.1155 +void
 20.1156 +}
 20.1157 +
 20.1158 +
 20.1159 +
 20.1160 +\vspace{0.3cm}
 20.1161 +\vspace{0.3cm}
 20.1162 +\vspace{0.3cm}
 20.1163  \subsubsection{RPC name:~get\_all}
 20.1164  
 20.1165  {\bf Overview:} 
 20.1166 @@ -12002,70 +11975,6 @@ value of the field
 20.1167  \vspace{0.3cm}
 20.1168  \vspace{0.3cm}
 20.1169  \vspace{0.3cm}
 20.1170 -\subsubsection{RPC name:~create}
 20.1171 -
 20.1172 -{\bf Overview:} 
 20.1173 -Create a new crashdump instance, and return its handle.
 20.1174 -
 20.1175 - \noindent {\bf Signature:} 
 20.1176 -\begin{verbatim} (crashdump ref) create (session_id s, crashdump record args)\end{verbatim}
 20.1177 -
 20.1178 -
 20.1179 -\noindent{\bf Arguments:}
 20.1180 -
 20.1181 - 
 20.1182 -\vspace{0.3cm}
 20.1183 -\begin{tabular}{|c|c|p{7cm}|}
 20.1184 - \hline
 20.1185 -{\bf type} & {\bf name} & {\bf description} \\ \hline
 20.1186 -{\tt crashdump record } & args & All constructor arguments \\ \hline 
 20.1187 -
 20.1188 -\end{tabular}
 20.1189 -
 20.1190 -\vspace{0.3cm}
 20.1191 -
 20.1192 - \noindent {\bf Return Type:} 
 20.1193 -{\tt 
 20.1194 -crashdump ref
 20.1195 -}
 20.1196 -
 20.1197 -
 20.1198 -reference to the newly created object
 20.1199 -\vspace{0.3cm}
 20.1200 -\vspace{0.3cm}
 20.1201 -\vspace{0.3cm}
 20.1202 -\subsubsection{RPC name:~destroy}
 20.1203 -
 20.1204 -{\bf Overview:} 
 20.1205 -Destroy the specified crashdump instance.
 20.1206 -
 20.1207 - \noindent {\bf Signature:} 
 20.1208 -\begin{verbatim} void destroy (session_id s, crashdump ref self)\end{verbatim}
 20.1209 -
 20.1210 -
 20.1211 -\noindent{\bf Arguments:}
 20.1212 -
 20.1213 - 
 20.1214 -\vspace{0.3cm}
 20.1215 -\begin{tabular}{|c|c|p{7cm}|}
 20.1216 - \hline
 20.1217 -{\bf type} & {\bf name} & {\bf description} \\ \hline
 20.1218 -{\tt crashdump ref } & self & reference to the object \\ \hline 
 20.1219 -
 20.1220 -\end{tabular}
 20.1221 -
 20.1222 -\vspace{0.3cm}
 20.1223 -
 20.1224 - \noindent {\bf Return Type:} 
 20.1225 -{\tt 
 20.1226 -void
 20.1227 -}
 20.1228 -
 20.1229 -
 20.1230 -
 20.1231 -\vspace{0.3cm}
 20.1232 -\vspace{0.3cm}
 20.1233 -\vspace{0.3cm}
 20.1234  \subsubsection{RPC name:~get\_by\_uuid}
 20.1235  
 20.1236  {\bf Overview:} 
 20.1237 @@ -12148,7 +12057,7 @@ Quals & Field & Type & Description \\
 20.1238  $\mathit{RO}_\mathit{ins}$ &  {\tt backend} & VM ref & the domain where the backend is located \\
 20.1239  \hline
 20.1240  \end{longtable}
 20.1241 -\subsection{Additional RPCs associated with class: VTPM}
 20.1242 +\subsection{RPCs associated with class: VTPM}
 20.1243  \subsubsection{RPC name:~get\_uuid}
 20.1244  
 20.1245  {\bf Overview:} 
 20.1246 @@ -12393,7 +12302,7 @@ Quals & Field & Type & Description \\
 20.1247  $\mathit{RW}$ &  {\tt other\_config} & (string $\rightarrow$ string) Map & additional configuration \\
 20.1248  \hline
 20.1249  \end{longtable}
 20.1250 -\subsection{Additional RPCs associated with class: console}
 20.1251 +\subsection{RPCs associated with class: console}
 20.1252  \subsubsection{RPC name:~get\_all}
 20.1253  
 20.1254  {\bf Overview:} 
 20.1255 @@ -12828,7 +12737,7 @@ Quals & Field & Type & Description \\
 20.1256  $\mathit{RW}$ &  {\tt fullname} & string & full name \\
 20.1257  \hline
 20.1258  \end{longtable}
 20.1259 -\subsection{Additional RPCs associated with class: user}
 20.1260 +\subsection{RPCs associated with class: user}
 20.1261  \subsubsection{RPC name:~get\_uuid}
 20.1262  
 20.1263  {\bf Overview:} 
 20.1264 @@ -13093,7 +13002,7 @@ all fields from the object
 20.1265  \section{Class: debug}
 20.1266  \subsection{Fields for class: debug}
 20.1267  {\bf Class debug has no fields.}
 20.1268 -\subsection{Additional RPCs associated with class: debug}
 20.1269 +\subsection{RPCs associated with class: debug}
 20.1270  \subsubsection{RPC name:~get\_all}
 20.1271  
 20.1272  {\bf Overview:} 
 20.1273 @@ -13467,6 +13376,15 @@ expected and actual VM state at the time
 20.1274  \begin{verbatim}VM_BAD_POWER_STATE(vm, expected, actual)\end{verbatim}
 20.1275  \begin{center}\rule{10em}{0.1pt}\end{center}
 20.1276  
 20.1277 +\subsubsection{VM\_HVM\_REQUIRED}
 20.1278 +
 20.1279 +HVM is required for this operation
 20.1280 +
 20.1281 +\vspace{0.3cm}
 20.1282 +{\bf Signature:}
 20.1283 +\begin{verbatim}VM_HVM_REQUIRED(vm)\end{verbatim}
 20.1284 +\begin{center}\rule{10em}{0.1pt}\end{center}
 20.1285 +
 20.1286  
 20.1287  
 20.1288  \newpage
    21.1 --- a/docs/xen-api/xenapi.tex	Wed Mar 21 17:03:00 2007 -0500
    21.2 +++ b/docs/xen-api/xenapi.tex	Wed Mar 21 18:08:31 2007 -0500
    21.3 @@ -16,6 +16,7 @@
    21.4  \usepackage{a4wide}
    21.5  \usepackage{graphics}
    21.6  \usepackage{longtable}
    21.7 +\usepackage{fancyhdr}
    21.8  
    21.9  \setlength\topskip{0cm}
   21.10  \setlength\topmargin{0cm}
   21.11 @@ -35,7 +36,7 @@
   21.12  
   21.13  \chapter{Introduction}
   21.14  
   21.15 -This document contains a proposal for a Xen Management API---an interface for
   21.16 +This document contains a description of the Xen Management API---an interface for
   21.17  remotely configuring and controlling virtualised guests running on a
   21.18  Xen-enabled host. 
   21.19  
    22.1 --- a/extras/mini-os/arch/x86/mm.c	Wed Mar 21 17:03:00 2007 -0500
    22.2 +++ b/extras/mini-os/arch/x86/mm.c	Wed Mar 21 18:08:31 2007 -0500
    22.3 @@ -49,7 +49,7 @@
    22.4  #endif
    22.5  
    22.6  unsigned long *phys_to_machine_mapping;
    22.7 -extern char *stack;
    22.8 +extern char stack[];
    22.9  extern void page_walk(unsigned long virt_addr);
   22.10  
   22.11  void new_pt_frame(unsigned long *pt_pfn, unsigned long prev_l_mfn, 
   22.12 @@ -453,7 +453,7 @@ void arch_init_mm(unsigned long* start_p
   22.13      printk("  _text:        %p\n", &_text);
   22.14      printk("  _etext:       %p\n", &_etext);
   22.15      printk("  _edata:       %p\n", &_edata);
   22.16 -    printk("  stack start:  %p\n", &stack);
   22.17 +    printk("  stack start:  %p\n", stack);
   22.18      printk("  _end:         %p\n", &_end);
   22.19  
   22.20      /* First page follows page table pages and 3 more pages (store page etc) */
    23.1 --- a/extras/mini-os/gnttab.c	Wed Mar 21 17:03:00 2007 -0500
    23.2 +++ b/extras/mini-os/gnttab.c	Wed Mar 21 18:08:31 2007 -0500
    23.3 @@ -135,7 +135,7 @@ gnttab_alloc_and_grant(void **map)
    23.4      return gref;
    23.5  }
    23.6  
    23.7 -static const char *gnttabop_error_msgs[] = GNTTABOP_error_msgs;
    23.8 +static const char * const gnttabop_error_msgs[] = GNTTABOP_error_msgs;
    23.9  
   23.10  const char *
   23.11  gnttabop_error(int16_t status)
    24.1 --- a/extras/mini-os/hypervisor.c	Wed Mar 21 17:03:00 2007 -0500
    24.2 +++ b/extras/mini-os/hypervisor.c	Wed Mar 21 18:08:31 2007 -0500
    24.3 @@ -35,8 +35,8 @@
    24.4  
    24.5  void do_hypervisor_callback(struct pt_regs *regs)
    24.6  {
    24.7 -    u32 	       l1, l2;
    24.8 -    unsigned int   l1i, l2i, port;
    24.9 +    unsigned long  l1, l2, l1i, l2i;
   24.10 +    unsigned int   port;
   24.11      int            cpu = 0;
   24.12      shared_info_t *s = HYPERVISOR_shared_info;
   24.13      vcpu_info_t   *vcpu_info = &s->vcpu_info[cpu];
    25.1 --- a/extras/mini-os/include/wait.h	Wed Mar 21 17:03:00 2007 -0500
    25.2 +++ b/extras/mini-os/include/wait.h	Wed Mar 21 18:08:31 2007 -0500
    25.3 @@ -74,6 +74,13 @@ static inline void wake_up(struct wait_q
    25.4      local_irq_restore(flags);   \
    25.5  } while (0)
    25.6  
    25.7 +#define remove_waiter(w) do {   \
    25.8 +    unsigned long flags;        \
    25.9 +    local_irq_save(flags);      \
   25.10 +    remove_wait_queue(&w);      \
   25.11 +    local_irq_restore(flags);   \
   25.12 +} while (0)
   25.13 +
   25.14  #define wait_event(wq, condition) do{             \
   25.15      unsigned long flags;                          \
   25.16      if(condition)                                 \
    26.1 --- a/extras/mini-os/include/xenbus.h	Wed Mar 21 17:03:00 2007 -0500
    26.2 +++ b/extras/mini-os/include/xenbus.h	Wed Mar 21 18:08:31 2007 -0500
    26.3 @@ -13,6 +13,7 @@ void init_xenbus(void);
    26.4  char *xenbus_read(xenbus_transaction_t xbt, const char *path, char **value);
    26.5  
    26.6  char *xenbus_watch_path(xenbus_transaction_t xbt, const char *path);
    26.7 +void wait_for_watch(void);
    26.8  char* xenbus_wait_for_value(const char*,const char*);
    26.9  
   26.10  /* Associates a value with a path.  Returns a malloc'd error string on
    27.1 --- a/extras/mini-os/xenbus/xenbus.c	Wed Mar 21 17:03:00 2007 -0500
    27.2 +++ b/extras/mini-os/xenbus/xenbus.c	Wed Mar 21 18:08:31 2007 -0500
    27.3 @@ -72,11 +72,12 @@ static void memcpy_from_ring(const void 
    27.4      memcpy(dest + c1, ring, c2);
    27.5  }
    27.6  
    27.7 -static inline void wait_for_watch(void)
    27.8 +void wait_for_watch(void)
    27.9  {
   27.10      DEFINE_WAIT(w);
   27.11      add_waiter(w,watch_queue);
   27.12      schedule();
   27.13 +    remove_waiter(w);
   27.14      wake(current);
   27.15  }
   27.16  
    28.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/cpu/mtrr/main-xen.c	Wed Mar 21 17:03:00 2007 -0500
    28.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/cpu/mtrr/main-xen.c	Wed Mar 21 18:08:31 2007 -0500
    28.3 @@ -14,11 +14,11 @@ static DEFINE_MUTEX(mtrr_mutex);
    28.4  void generic_get_mtrr(unsigned int reg, unsigned long *base,
    28.5  		      unsigned int *size, mtrr_type * type)
    28.6  {
    28.7 -	dom0_op_t op;
    28.8 +	struct xen_platform_op op;
    28.9  
   28.10 -	op.cmd = DOM0_READ_MEMTYPE;
   28.11 +	op.cmd = XENPF_read_memtype;
   28.12  	op.u.read_memtype.reg = reg;
   28.13 -	(void)HYPERVISOR_dom0_op(&op);
   28.14 +	(void)HYPERVISOR_platform_op(&op);
   28.15  
   28.16  	*size = op.u.read_memtype.nr_mfns;
   28.17  	*base = op.u.read_memtype.mfn;
   28.18 @@ -36,12 +36,12 @@ unsigned int *usage_table;
   28.19  
   28.20  static void __init set_num_var_ranges(void)
   28.21  {
   28.22 -	dom0_op_t op;
   28.23 +	struct xen_platform_op op;
   28.24  
   28.25  	for (num_var_ranges = 0; ; num_var_ranges++) {
   28.26 -		op.cmd = DOM0_READ_MEMTYPE;
   28.27 +		op.cmd = XENPF_read_memtype;
   28.28  		op.u.read_memtype.reg = num_var_ranges;
   28.29 -		if (HYPERVISOR_dom0_op(&op) != 0)
   28.30 +		if (HYPERVISOR_platform_op(&op) != 0)
   28.31  			break;
   28.32  	}
   28.33  }
   28.34 @@ -64,15 +64,15 @@ int mtrr_add_page(unsigned long base, un
   28.35  		  unsigned int type, char increment)
   28.36  {
   28.37  	int error;
   28.38 -	dom0_op_t op;
   28.39 +	struct xen_platform_op op;
   28.40  
   28.41  	mutex_lock(&mtrr_mutex);
   28.42  
   28.43 -	op.cmd = DOM0_ADD_MEMTYPE;
   28.44 +	op.cmd = XENPF_add_memtype;
   28.45  	op.u.add_memtype.mfn     = base;
   28.46  	op.u.add_memtype.nr_mfns = size;
   28.47  	op.u.add_memtype.type    = type;
   28.48 -	error = HYPERVISOR_dom0_op(&op);
   28.49 +	error = HYPERVISOR_platform_op(&op);
   28.50  	if (error) {
   28.51  		mutex_unlock(&mtrr_mutex);
   28.52  		BUG_ON(error > 0);
   28.53 @@ -117,7 +117,7 @@ int mtrr_del_page(int reg, unsigned long
   28.54  	unsigned long lbase;
   28.55  	unsigned int lsize;
   28.56  	int error = -EINVAL;
   28.57 -	dom0_op_t op;
   28.58 +	struct xen_platform_op op;
   28.59  
   28.60  	mutex_lock(&mtrr_mutex);
   28.61  
   28.62 @@ -141,10 +141,10 @@ int mtrr_del_page(int reg, unsigned long
   28.63  		goto out;
   28.64  	}
   28.65  	if (--usage_table[reg] < 1) {
   28.66 -		op.cmd = DOM0_DEL_MEMTYPE;
   28.67 +		op.cmd = XENPF_del_memtype;
   28.68  		op.u.del_memtype.handle = 0;
   28.69  		op.u.del_memtype.reg    = reg;
   28.70 -		error = HYPERVISOR_dom0_op(&op);
   28.71 +		error = HYPERVISOR_platform_op(&op);
   28.72  		if (error) {
   28.73  			BUG_ON(error > 0);
   28.74  			goto out;
    29.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c	Wed Mar 21 17:03:00 2007 -0500
    29.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c	Wed Mar 21 18:08:31 2007 -0500
    29.3 @@ -2510,10 +2510,10 @@ static int __init io_apic_bug_finalize(v
    29.4  	if(sis_apic_bug == -1)
    29.5  		sis_apic_bug = 0;
    29.6  	if (is_initial_xendomain()) {
    29.7 -		dom0_op_t op = { .cmd = DOM0_PLATFORM_QUIRK };
    29.8 +		struct xen_platform_op op = { .cmd = XENPF_platform_quirk };
    29.9  		op.u.platform_quirk.quirk_id = sis_apic_bug ?
   29.10  			QUIRK_IOAPIC_BAD_REGSEL : QUIRK_IOAPIC_GOOD_REGSEL;
   29.11 -		HYPERVISOR_dom0_op(&op);
   29.12 +		HYPERVISOR_platform_op(&op);
   29.13  	}
   29.14  	return 0;
   29.15  }
    30.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/ioport-xen.c	Wed Mar 21 17:03:00 2007 -0500
    30.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/ioport-xen.c	Wed Mar 21 18:08:31 2007 -0500
    30.3 @@ -81,7 +81,7 @@ asmlinkage long sys_ioperm(unsigned long
    30.4  		t->io_bitmap_ptr = bitmap;
    30.5  		set_thread_flag(TIF_IO_BITMAP);
    30.6  
    30.7 -		set_iobitmap.bitmap   = (char *)bitmap;
    30.8 +		set_xen_guest_handle(set_iobitmap.bitmap, (char *)bitmap);
    30.9  		set_iobitmap.nr_ports = IO_BITMAP_BITS;
   30.10  		HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &set_iobitmap);
   30.11  	}
    31.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/microcode-xen.c	Wed Mar 21 17:03:00 2007 -0500
    31.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/microcode-xen.c	Wed Mar 21 18:08:31 2007 -0500
    31.3 @@ -71,12 +71,12 @@ static int do_microcode_update (const vo
    31.4  		return -ENOMEM;
    31.5  
    31.6  	if (copy_from_user(kbuf, ubuf, len) == 0) {
    31.7 -		dom0_op_t op;
    31.8 +		struct xen_platform_op op;
    31.9  
   31.10 -		op.cmd = DOM0_MICROCODE;
   31.11 +		op.cmd = XENPF_microcode_update;
   31.12  		set_xen_guest_handle(op.u.microcode.data, kbuf);
   31.13  		op.u.microcode.length = len;
   31.14 -		err = HYPERVISOR_dom0_op(&op);
   31.15 +		err = HYPERVISOR_platform_op(&op);
   31.16  	} else
   31.17  		err = -EFAULT;
   31.18  
    32.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c	Wed Mar 21 17:03:00 2007 -0500
    32.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c	Wed Mar 21 18:08:31 2007 -0500
    32.3 @@ -307,7 +307,8 @@ void exit_thread(void)
    32.4  	if (unlikely(test_thread_flag(TIF_IO_BITMAP))) {
    32.5  		struct task_struct *tsk = current;
    32.6  		struct thread_struct *t = &tsk->thread;
    32.7 -		struct physdev_set_iobitmap set_iobitmap = { 0 };
    32.8 +		struct physdev_set_iobitmap set_iobitmap;
    32.9 +		memset(&set_iobitmap, 0, sizeof(set_iobitmap));
   32.10  		HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &set_iobitmap);
   32.11  		kfree(t->io_bitmap_ptr);
   32.12  		t->io_bitmap_ptr = NULL;
   32.13 @@ -606,7 +607,8 @@ struct task_struct fastcall * __switch_t
   32.14  	}
   32.15  
   32.16  	if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) {
   32.17 -		iobmp_op.bitmap   = (char *)next->io_bitmap_ptr;
   32.18 +		set_xen_guest_handle(iobmp_op.bitmap,
   32.19 +				     (char *)next->io_bitmap_ptr);
   32.20  		iobmp_op.nr_ports = next->io_bitmap_ptr ? IO_BITMAP_BITS : 0;
   32.21  		mcl->op      = __HYPERVISOR_physdev_op;
   32.22  		mcl->args[0] = PHYSDEVOP_set_iobitmap;
    33.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/quirks-xen.c	Wed Mar 21 17:03:00 2007 -0500
    33.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/quirks-xen.c	Wed Mar 21 18:08:31 2007 -0500
    33.3 @@ -30,11 +30,11 @@ static void __devinit quirk_intel_irqbal
    33.4  	raw_pci_ops->read(0, 0, 0x40, 0x4c, 2, &word);
    33.5  
    33.6  	if (!(word & (1 << 13))) {
    33.7 -		dom0_op_t op;
    33.8 +		struct xen_platform_op op;
    33.9  		printk(KERN_INFO "Disabling irq balancing and affinity\n");
   33.10 -		op.cmd = DOM0_PLATFORM_QUIRK;
   33.11 +		op.cmd = XENPF_platform_quirk;
   33.12  		op.u.platform_quirk.quirk_id = QUIRK_NOIRQBALANCING;
   33.13 -		(void)HYPERVISOR_dom0_op(&op);
   33.14 +		(void)HYPERVISOR_platform_op(&op);
   33.15  	}
   33.16  
   33.17  	/* put back the original value for config space*/
    34.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c	Wed Mar 21 17:03:00 2007 -0500
    34.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c	Wed Mar 21 18:08:31 2007 -0500
    34.3 @@ -435,7 +435,7 @@ int do_settimeofday(struct timespec *tv)
    34.4  	s64 nsec;
    34.5  	unsigned int cpu;
    34.6  	struct shadow_time_info *shadow;
    34.7 -	dom0_op_t op;
    34.8 +	struct xen_platform_op op;
    34.9  
   34.10  	if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
   34.11  		return -EINVAL;
   34.12 @@ -460,11 +460,11 @@ int do_settimeofday(struct timespec *tv)
   34.13  	__normalize_time(&sec, &nsec);
   34.14  
   34.15  	if (is_initial_xendomain() && !independent_wallclock) {
   34.16 -		op.cmd = DOM0_SETTIME;
   34.17 +		op.cmd = XENPF_settime;
   34.18  		op.u.settime.secs        = sec;
   34.19  		op.u.settime.nsecs       = nsec;
   34.20  		op.u.settime.system_time = shadow->system_timestamp;
   34.21 -		HYPERVISOR_dom0_op(&op);
   34.22 +		HYPERVISOR_platform_op(&op);
   34.23  		update_wallclock();
   34.24  	} else if (independent_wallclock) {
   34.25  		nsec -= shadow->system_timestamp;
   34.26 @@ -488,7 +488,7 @@ static void sync_xen_wallclock(unsigned 
   34.27  {
   34.28  	time_t sec;
   34.29  	s64 nsec;
   34.30 -	dom0_op_t op;
   34.31 +	struct xen_platform_op op;
   34.32  
   34.33  	if (!ntp_synced() || independent_wallclock || !is_initial_xendomain())
   34.34  		return;
   34.35 @@ -499,11 +499,11 @@ static void sync_xen_wallclock(unsigned 
   34.36  	nsec = xtime.tv_nsec + ((jiffies - wall_jiffies) * (u64)NS_PER_TICK);
   34.37  	__normalize_time(&sec, &nsec);
   34.38  
   34.39 -	op.cmd = DOM0_SETTIME;
   34.40 +	op.cmd = XENPF_settime;
   34.41  	op.u.settime.secs        = sec;
   34.42  	op.u.settime.nsecs       = nsec;
   34.43  	op.u.settime.system_time = processed_system_time;
   34.44 -	HYPERVISOR_dom0_op(&op);
   34.45 +	HYPERVISOR_platform_op(&op);
   34.46  
   34.47  	update_wallclock();
   34.48  
   34.49 @@ -907,6 +907,10 @@ static void setup_cpu0_timer_irq(void)
   34.50  	BUG_ON(per_cpu(timer_irq, 0) < 0);
   34.51  }
   34.52  
   34.53 +static struct vcpu_set_periodic_timer xen_set_periodic_tick = {
   34.54 +	.period_ns = NS_PER_TICK
   34.55 +};
   34.56 +
   34.57  void __init time_init(void)
   34.58  {
   34.59  #ifdef CONFIG_HPET_TIMER
   34.60 @@ -919,6 +923,10 @@ void __init time_init(void)
   34.61  		return;
   34.62  	}
   34.63  #endif
   34.64 +
   34.65 +	HYPERVISOR_vcpu_op(VCPUOP_set_periodic_timer, 0,
   34.66 +			   &xen_set_periodic_tick);
   34.67 +
   34.68  	get_time_values_from_xen(0);
   34.69  
   34.70  	processed_system_time = per_cpu(shadow_time, 0).system_timestamp;
   34.71 @@ -976,8 +984,10 @@ EXPORT_SYMBOL(jiffies_to_st);
   34.72   */
   34.73  static void stop_hz_timer(void)
   34.74  {
   34.75 +	struct vcpu_set_singleshot_timer singleshot;
   34.76  	unsigned int cpu = smp_processor_id();
   34.77  	unsigned long j;
   34.78 +	int rc;
   34.79  
   34.80  	cpu_set(cpu, nohz_cpu_mask);
   34.81  
   34.82 @@ -997,8 +1007,16 @@ static void stop_hz_timer(void)
   34.83  		j = jiffies + 1;
   34.84  	}
   34.85  
   34.86 -	if (HYPERVISOR_set_timer_op(jiffies_to_st(j)) != 0)
   34.87 -		BUG();
   34.88 +	singleshot.timeout_abs_ns = jiffies_to_st(j);
   34.89 +	singleshot.flags = 0;
   34.90 +	rc = HYPERVISOR_vcpu_op(VCPUOP_set_singleshot_timer, cpu, &singleshot);
   34.91 +#ifdef CONFIG_XEN_COMPAT_030004
   34.92 +	if (rc) {
   34.93 +		BUG_ON(rc != -ENOSYS);
   34.94 +		rc = HYPERVISOR_set_timer_op(singleshot.timeout_abs_ns);
   34.95 +	}
   34.96 +#endif
   34.97 +	BUG_ON(rc);
   34.98  }
   34.99  
  34.100  static void start_hz_timer(void)
  34.101 @@ -1030,6 +1048,8 @@ void time_resume(void)
  34.102  	init_cpu_khz();
  34.103  
  34.104  	for_each_online_cpu(cpu) {
  34.105 +		HYPERVISOR_vcpu_op(VCPUOP_set_periodic_timer, cpu,
  34.106 +				   &xen_set_periodic_tick);
  34.107  		get_time_values_from_xen(cpu);
  34.108  		per_cpu(processed_system_time, cpu) =
  34.109  			per_cpu(shadow_time, 0).system_timestamp;
  34.110 @@ -1050,6 +1070,9 @@ int local_setup_timer(unsigned int cpu)
  34.111  
  34.112  	BUG_ON(cpu == 0);
  34.113  
  34.114 +	HYPERVISOR_vcpu_op(VCPUOP_set_periodic_timer, cpu,
  34.115 +			   &xen_set_periodic_tick);
  34.116 +
  34.117  	do {
  34.118  		seq = read_seqbegin(&xtime_lock);
  34.119  		/* Use cpu0 timestamp: cpu's shadow is not initialised yet. */
    35.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/vsyscall-note-xen.S	Wed Mar 21 17:03:00 2007 -0500
    35.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/vsyscall-note-xen.S	Wed Mar 21 18:08:31 2007 -0500
    35.3 @@ -28,5 +28,5 @@
    35.4  #define NOTE_KERNELCAP_END ASM_ELF_NOTE_END
    35.5  
    35.6  NOTE_KERNELCAP_BEGIN(1, 1)
    35.7 -NOTE_KERNELCAP(1, "nosegneg")  /* Change 1 back to 0 when glibc is fixed! */
    35.8 +NOTE_KERNELCAP(0, "nosegneg")
    35.9  NOTE_KERNELCAP_END
    36.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c	Wed Mar 21 17:03:00 2007 -0500
    36.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c	Wed Mar 21 18:08:31 2007 -0500
    36.3 @@ -146,7 +146,7 @@ void xen_tlb_flush_mask(cpumask_t *mask)
    36.4  	if ( cpus_empty(*mask) )
    36.5  		return;
    36.6  	op.cmd = MMUEXT_TLB_FLUSH_MULTI;
    36.7 -	op.arg2.vcpumask = mask->bits;
    36.8 +	set_xen_guest_handle(op.arg2.vcpumask, mask->bits);
    36.9  	BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
   36.10  }
   36.11  
   36.12 @@ -165,7 +165,7 @@ void xen_invlpg_mask(cpumask_t *mask, un
   36.13  		return;
   36.14  	op.cmd = MMUEXT_INVLPG_MULTI;
   36.15  	op.arg1.linear_addr = ptr & PAGE_MASK;
   36.16 -	op.arg2.vcpumask    = mask->bits;
   36.17 +	set_xen_guest_handle(op.arg2.vcpumask, mask->bits);
   36.18  	BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
   36.19  }
   36.20  
    37.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c	Wed Mar 21 17:03:00 2007 -0500
    37.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c	Wed Mar 21 18:08:31 2007 -0500
    37.3 @@ -256,8 +256,9 @@ void pte_free(struct page *pte)
    37.4  		unsigned long va = (unsigned long)__va(pfn << PAGE_SHIFT);
    37.5  
    37.6  		if (!pte_write(*virt_to_ptep(va)))
    37.7 -			BUG_ON(HYPERVISOR_update_va_mapping(
    37.8 -			       va, pfn_pte(pfn, PAGE_KERNEL), 0));
    37.9 +			if (HYPERVISOR_update_va_mapping(
   37.10 +				va, pfn_pte(pfn, PAGE_KERNEL), 0))
   37.11 +				BUG();
   37.12  	} else
   37.13  		clear_bit(PG_pinned, &pte->flags);
   37.14  
   37.15 @@ -600,7 +601,7 @@ static void pgd_walk(pgd_t *pgd_base, pg
   37.16  	int    g, u, m, rc;
   37.17  
   37.18  	if (xen_feature(XENFEAT_auto_translated_physmap))
   37.19 -		return 0;
   37.20 +		return;
   37.21  
   37.22  	for (g = 0; g < USER_PTRS_PER_PGD; g++, pgd++) {
   37.23  		if (pgd_none(*pgd))
   37.24 @@ -672,14 +673,23 @@ void mm_unpin(struct mm_struct *mm)
   37.25  void mm_pin_all(void)
   37.26  {
   37.27  	struct page *page;
   37.28 +	unsigned long flags;
   37.29  
   37.30  	if (xen_feature(XENFEAT_writable_page_tables))
   37.31  		return;
   37.32  
   37.33 +	/*
   37.34 +	 * Allow uninterrupted access to the pgd_list. Also protects
   37.35 +	 * __pgd_pin() by disabling preemption.
   37.36 +	 * All other CPUs must be at a safe point (e.g., in stop_machine
   37.37 +	 * or offlined entirely).
   37.38 +	 */
   37.39 +	spin_lock_irqsave(&pgd_lock, flags);
   37.40  	for (page = pgd_list; page; page = (struct page *)page->index) {
   37.41  		if (!test_bit(PG_pinned, &page->flags))
   37.42  			__pgd_pin((pgd_t *)page_address(page));
   37.43  	}
   37.44 +	spin_unlock_irqrestore(&pgd_lock, flags);
   37.45  }
   37.46  
   37.47  void _arch_dup_mmap(struct mm_struct *mm)
    38.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen/xcom_hcall.c	Wed Mar 21 17:03:00 2007 -0500
    38.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xcom_hcall.c	Wed Mar 21 18:08:31 2007 -0500
    38.3 @@ -21,7 +21,7 @@
    38.4  #include <linux/gfp.h>
    38.5  #include <linux/module.h>
    38.6  #include <xen/interface/xen.h>
    38.7 -#include <xen/interface/dom0_ops.h>
    38.8 +#include <xen/interface/platform.h>
    38.9  #include <xen/interface/memory.h>
   38.10  #include <xen/interface/xencomm.h>
   38.11  #include <xen/interface/version.h>
    39.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen/xcom_mini.c	Wed Mar 21 17:03:00 2007 -0500
    39.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xcom_mini.c	Wed Mar 21 18:08:31 2007 -0500
    39.3 @@ -20,7 +20,7 @@
    39.4  #include <linux/kernel.h>
    39.5  #include <linux/module.h>
    39.6  #include <xen/interface/xen.h>
    39.7 -#include <xen/interface/dom0_ops.h>
    39.8 +#include <xen/interface/platform.h>
    39.9  #include <xen/interface/memory.h>
   39.10  #include <xen/interface/xencomm.h>
   39.11  #include <xen/interface/version.h>
    40.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c	Wed Mar 21 17:03:00 2007 -0500
    40.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c	Wed Mar 21 18:08:31 2007 -0500
    40.3 @@ -22,7 +22,7 @@
    40.4  #include <linux/gfp.h>
    40.5  #include <linux/module.h>
    40.6  #include <xen/interface/xen.h>
    40.7 -#include <xen/interface/dom0_ops.h>
    40.8 +#include <xen/interface/platform.h>
    40.9  #define __XEN__
   40.10  #include <xen/interface/domctl.h>
   40.11  #include <xen/interface/sysctl.h>
   40.12 @@ -40,25 +40,25 @@
   40.13  #define ROUND_DIV(v,s) (((v) + (s) - 1) / (s))
   40.14  
   40.15  static int
   40.16 -xencomm_privcmd_dom0_op(privcmd_hypercall_t *hypercall)
   40.17 +xencomm_privcmd_platform_op(privcmd_hypercall_t *hypercall)
   40.18  {
   40.19 -	dom0_op_t kern_op;
   40.20 -	dom0_op_t __user *user_op = (dom0_op_t __user *)hypercall->arg[0];
   40.21 +	struct xen_platform_op kern_op;
   40.22 +	struct xen_platform_op __user *user_op = (struct xen_platform_op __user *)hypercall->arg[0];
   40.23  	struct xencomm_handle *op_desc;
   40.24  	struct xencomm_handle *desc = NULL;
   40.25  	int ret = 0;
   40.26  
   40.27 -	if (copy_from_user(&kern_op, user_op, sizeof(dom0_op_t)))
   40.28 +	if (copy_from_user(&kern_op, user_op, sizeof(struct xen_platform_op)))
   40.29  		return -EFAULT;
   40.30  
   40.31 -	if (kern_op.interface_version != DOM0_INTERFACE_VERSION)
   40.32 +	if (kern_op.interface_version != XENPF_INTERFACE_VERSION)
   40.33  		return -EACCES;
   40.34  
   40.35  	op_desc = xencomm_create_inline(&kern_op);
   40.36  
   40.37  	switch (kern_op.cmd) {
   40.38  	default:
   40.39 -		printk("%s: unknown dom0 cmd %d\n", __func__, kern_op.cmd);
   40.40 +		printk("%s: unknown platform cmd %d\n", __func__, kern_op.cmd);
   40.41  		return -ENOSYS;
   40.42  	}
   40.43  
   40.44 @@ -67,10 +67,10 @@ xencomm_privcmd_dom0_op(privcmd_hypercal
   40.45  		return ret;
   40.46  	}
   40.47  
   40.48 -	ret = xencomm_arch_hypercall_dom0_op(op_desc);
   40.49 +	ret = xencomm_arch_hypercall_platform_op(op_desc);
   40.50  
   40.51  	/* FIXME: should we restore the handle?  */
   40.52 -	if (copy_to_user(user_op, &kern_op, sizeof(dom0_op_t)))
   40.53 +	if (copy_to_user(user_op, &kern_op, sizeof(struct xen_platform_op)))
   40.54  		ret = -EFAULT;
   40.55  
   40.56  	if (desc)
   40.57 @@ -638,8 +638,8 @@ int
   40.58  privcmd_hypercall(privcmd_hypercall_t *hypercall)
   40.59  {
   40.60  	switch (hypercall->op) {
   40.61 -	case __HYPERVISOR_dom0_op:
   40.62 -		return xencomm_privcmd_dom0_op(hypercall);
   40.63 +	case __HYPERVISOR_platform_op:
   40.64 +		return xencomm_privcmd_platform_op(hypercall);
   40.65  	case __HYPERVISOR_domctl:
   40.66  		return xencomm_privcmd_domctl(hypercall);
   40.67  	case __HYPERVISOR_sysctl:
    41.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c	Wed Mar 21 17:03:00 2007 -0500
    41.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c	Wed Mar 21 18:08:31 2007 -0500
    41.3 @@ -59,7 +59,7 @@ asmlinkage long sys_ioperm(unsigned long
    41.4  		memset(bitmap, 0xff, IO_BITMAP_BYTES);
    41.5  		t->io_bitmap_ptr = bitmap;
    41.6  
    41.7 -		set_iobitmap.bitmap   = (char *)bitmap;
    41.8 +		set_xen_guest_handle(set_iobitmap.bitmap, (char *)bitmap);
    41.9  		set_iobitmap.nr_ports = IO_BITMAP_BITS;
   41.10  		HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &set_iobitmap);
   41.11  	}
    42.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c	Wed Mar 21 17:03:00 2007 -0500
    42.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c	Wed Mar 21 18:08:31 2007 -0500
    42.3 @@ -50,7 +50,7 @@
    42.4  #include <asm/pda.h>
    42.5  #include <asm/prctl.h>
    42.6  #include <asm/kdebug.h>
    42.7 -#include <xen/interface/dom0_ops.h>
    42.8 +#include <xen/interface/platform.h>
    42.9  #include <xen/interface/physdev.h>
   42.10  #include <xen/interface/vcpu.h>
   42.11  #include <asm/desc.h>
   42.12 @@ -304,7 +304,8 @@ void exit_thread(void)
   42.13  		struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
   42.14  #endif
   42.15  #ifdef CONFIG_XEN
   42.16 -		struct physdev_set_iobitmap iobmp_op = { 0 };
   42.17 +		struct physdev_set_iobitmap iobmp_op;
   42.18 +		memset(&iobmp_op, 0, sizeof(iobmp_op));
   42.19  #endif
   42.20  
   42.21  		kfree(t->io_bitmap_ptr);
   42.22 @@ -540,7 +541,8 @@ static inline void __save_init_fpu( stru
   42.23  	}
   42.24  
   42.25  	if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) {
   42.26 -		iobmp_op.bitmap   = (char *)next->io_bitmap_ptr;
   42.27 +		set_xen_guest_handle(iobmp_op.bitmap,
   42.28 +				     (char *)next->io_bitmap_ptr);
   42.29  		iobmp_op.nr_ports = next->io_bitmap_ptr ? IO_BITMAP_BITS : 0;
   42.30  		mcl->op      = __HYPERVISOR_physdev_op;
   42.31  		mcl->args[0] = PHYSDEVOP_set_iobitmap;
    43.1 --- a/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c	Wed Mar 21 17:03:00 2007 -0500
    43.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c	Wed Mar 21 18:08:31 2007 -0500
    43.3 @@ -597,8 +597,10 @@ void __init xen_init_pt(void)
    43.4  	early_make_page_readonly(level2_kernel_pgt,
    43.5  				 XENFEAT_writable_page_tables);
    43.6  
    43.7 -	xen_pgd_pin(__pa_symbol(init_level4_pgt));
    43.8 -	xen_pgd_pin(__pa_symbol(init_level4_user_pgt));
    43.9 +	if (!xen_feature(XENFEAT_writable_page_tables)) {
   43.10 +		xen_pgd_pin(__pa_symbol(init_level4_pgt));
   43.11 +		xen_pgd_pin(__pa_symbol(init_level4_user_pgt));
   43.12 +	}
   43.13  
   43.14  	set_pgd((pgd_t *)(init_level4_user_pgt + 511), 
   43.15  		mk_kernel_pgd(__pa_symbol(level3_user_pgt)));
    44.1 --- a/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c	Wed Mar 21 17:03:00 2007 -0500
    44.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c	Wed Mar 21 18:08:31 2007 -0500
    44.3 @@ -79,14 +79,17 @@ void mm_pin(struct mm_struct *mm)
    44.4  	spin_lock(&mm->page_table_lock);
    44.5  
    44.6  	mm_walk(mm, PAGE_KERNEL_RO);
    44.7 -	BUG_ON(HYPERVISOR_update_va_mapping(
    44.8 -		       (unsigned long)mm->pgd,
    44.9 -		       pfn_pte(virt_to_phys(mm->pgd)>>PAGE_SHIFT, PAGE_KERNEL_RO),
   44.10 -		       UVMF_TLB_FLUSH));
   44.11 -	BUG_ON(HYPERVISOR_update_va_mapping(
   44.12 -		       (unsigned long)__user_pgd(mm->pgd),
   44.13 -		       pfn_pte(virt_to_phys(__user_pgd(mm->pgd))>>PAGE_SHIFT, PAGE_KERNEL_RO),
   44.14 -		       UVMF_TLB_FLUSH));
   44.15 +	if (HYPERVISOR_update_va_mapping(
   44.16 +		(unsigned long)mm->pgd,
   44.17 +		pfn_pte(virt_to_phys(mm->pgd)>>PAGE_SHIFT, PAGE_KERNEL_RO),
   44.18 +		UVMF_TLB_FLUSH))
   44.19 +		BUG();
   44.20 +	if (HYPERVISOR_update_va_mapping(
   44.21 +		(unsigned long)__user_pgd(mm->pgd),
   44.22 +		pfn_pte(virt_to_phys(__user_pgd(mm->pgd))>>PAGE_SHIFT,
   44.23 +			PAGE_KERNEL_RO),
   44.24 +		UVMF_TLB_FLUSH))
   44.25 +		BUG();
   44.26  	xen_pgd_pin(__pa(mm->pgd)); /* kernel */
   44.27  	xen_pgd_pin(__pa(__user_pgd(mm->pgd))); /* user */
   44.28  	mm->context.pinned = 1;
   44.29 @@ -106,12 +109,15 @@ void mm_unpin(struct mm_struct *mm)
   44.30  
   44.31  	xen_pgd_unpin(__pa(mm->pgd));
   44.32  	xen_pgd_unpin(__pa(__user_pgd(mm->pgd)));
   44.33 -	BUG_ON(HYPERVISOR_update_va_mapping(
   44.34 -		       (unsigned long)mm->pgd,
   44.35 -		       pfn_pte(virt_to_phys(mm->pgd)>>PAGE_SHIFT, PAGE_KERNEL), 0));
   44.36 -	BUG_ON(HYPERVISOR_update_va_mapping(
   44.37 -		       (unsigned long)__user_pgd(mm->pgd),
   44.38 -		       pfn_pte(virt_to_phys(__user_pgd(mm->pgd))>>PAGE_SHIFT, PAGE_KERNEL), 0));
   44.39 +	if (HYPERVISOR_update_va_mapping(
   44.40 +		(unsigned long)mm->pgd,
   44.41 +		pfn_pte(virt_to_phys(mm->pgd)>>PAGE_SHIFT, PAGE_KERNEL), 0))
   44.42 +		BUG();
   44.43 +	if (HYPERVISOR_update_va_mapping(
   44.44 +		(unsigned long)__user_pgd(mm->pgd),
   44.45 +		pfn_pte(virt_to_phys(__user_pgd(mm->pgd))>>PAGE_SHIFT,
   44.46 +			PAGE_KERNEL), 0))
   44.47 +		BUG();
   44.48  	mm_walk(mm, PAGE_KERNEL);
   44.49  	xen_tlb_flush();
   44.50  	mm->context.pinned = 0;
   44.51 @@ -127,43 +133,50 @@ void mm_pin_all(void)
   44.52  	if (xen_feature(XENFEAT_writable_page_tables))
   44.53  		return;
   44.54  
   44.55 +	/*
   44.56 +	 * Allow uninterrupted access to the mm_unpinned list. We don't
   44.57 +	 * actually take the mm_unpinned_lock as it is taken inside mm_pin().
   44.58 +	 * All other CPUs must be at a safe point (e.g., in stop_machine
   44.59 +	 * or offlined entirely).
   44.60 +	 */
   44.61 +	preempt_disable();
   44.62  	while (!list_empty(&mm_unpinned))	
   44.63  		mm_pin(list_entry(mm_unpinned.next, struct mm_struct,
   44.64  				  context.unpinned));
   44.65 +	preempt_enable();
   44.66  }
   44.67  
   44.68  void _arch_dup_mmap(struct mm_struct *mm)
   44.69  {
   44.70 -    if (!mm->context.pinned)
   44.71 -        mm_pin(mm);
   44.72 +	if (!mm->context.pinned)
   44.73 +		mm_pin(mm);
   44.74  }
   44.75  
   44.76  void _arch_exit_mmap(struct mm_struct *mm)
   44.77  {
   44.78 -    struct task_struct *tsk = current;
   44.79 +	struct task_struct *tsk = current;
   44.80 +
   44.81 +	task_lock(tsk);
   44.82  
   44.83 -    task_lock(tsk);
   44.84 +	/*
   44.85 +	 * We aggressively remove defunct pgd from cr3. We execute unmap_vmas()
   44.86 +	 * *much* faster this way, as no tlb flushes means bigger wrpt batches.
   44.87 +	 */
   44.88 +	if (tsk->active_mm == mm) {
   44.89 +		tsk->active_mm = &init_mm;
   44.90 +		atomic_inc(&init_mm.mm_count);
   44.91  
   44.92 -    /*
   44.93 -     * We aggressively remove defunct pgd from cr3. We execute unmap_vmas()
   44.94 -     * *much* faster this way, as no tlb flushes means bigger wrpt batches.
   44.95 -     */
   44.96 -    if ( tsk->active_mm == mm )
   44.97 -    {
   44.98 -        tsk->active_mm = &init_mm;
   44.99 -        atomic_inc(&init_mm.mm_count);
  44.100 +		switch_mm(mm, &init_mm, tsk);
  44.101 +
  44.102 +		atomic_dec(&mm->mm_count);
  44.103 +		BUG_ON(atomic_read(&mm->mm_count) == 0);
  44.104 +	}
  44.105  
  44.106 -        switch_mm(mm, &init_mm, tsk);
  44.107 -
  44.108 -        atomic_dec(&mm->mm_count);
  44.109 -        BUG_ON(atomic_read(&mm->mm_count) == 0);
  44.110 -    }
  44.111 +	task_unlock(tsk);
  44.112  
  44.113 -    task_unlock(tsk);
  44.114 -
  44.115 -    if ( mm->context.pinned && (atomic_read(&mm->mm_count) == 1) &&
  44.116 -         !mm->context.has_foreign_mappings )
  44.117 -        mm_unpin(mm);
  44.118 +	if ( mm->context.pinned && (atomic_read(&mm->mm_count) == 1) &&
  44.119 +	     !mm->context.has_foreign_mappings )
  44.120 +		mm_unpin(mm);
  44.121  }
  44.122  
  44.123  struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
  44.124 @@ -183,8 +196,9 @@ void pte_free(struct page *pte)
  44.125  	unsigned long va = (unsigned long)__va(page_to_pfn(pte)<<PAGE_SHIFT);
  44.126  
  44.127  	if (!pte_write(*virt_to_ptep(va)))
  44.128 -		BUG_ON(HYPERVISOR_update_va_mapping(
  44.129 -			va, pfn_pte(page_to_pfn(pte), PAGE_KERNEL), 0));
  44.130 +		if (HYPERVISOR_update_va_mapping(
  44.131 +			va, pfn_pte(page_to_pfn(pte), PAGE_KERNEL), 0))
  44.132 +			BUG();
  44.133  
  44.134  	ClearPageForeign(pte);
  44.135  	init_page_count(pte);
    45.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c	Wed Mar 21 17:03:00 2007 -0500
    45.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c	Wed Mar 21 18:08:31 2007 -0500
    45.3 @@ -504,7 +504,6 @@ static struct tpm_vendor_specific tpm_vt
    45.4  };
    45.5  
    45.6  struct tpm_chip *init_vtpm(struct device *dev,
    45.7 -                           struct tpm_virtual_device *tvd,
    45.8                             struct tpm_private *tp)
    45.9  {
   45.10  	long rc;
   45.11 @@ -516,7 +515,6 @@ struct tpm_chip *init_vtpm(struct device
   45.12  		return ERR_PTR(-ENOMEM);
   45.13  
   45.14  	vtpm_state_init(vtpms);
   45.15 -	vtpms->tpmvd = tvd;
   45.16  	vtpms->tpm_private = tp;
   45.17  
   45.18  	chip = tpm_register_hardware(dev, &tpm_vtpm);
    46.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.h	Wed Mar 21 17:03:00 2007 -0500
    46.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.h	Wed Mar 21 18:08:31 2007 -0500
    46.3 @@ -4,16 +4,6 @@
    46.4  struct tpm_chip;
    46.5  struct tpm_private;
    46.6  
    46.7 -struct tpm_virtual_device {
    46.8 -	/*
    46.9 -	 * This field indicates the maximum size the driver can
   46.10 -	 * transfer in one chunk. It is filled in by the front-end
   46.11 -	 * driver and should be propagated to the generic tpm driver
   46.12 -	 * for allocation of buffers.
   46.13 -	 */
   46.14 -	unsigned int max_tx_size;
   46.15 -};
   46.16 -
   46.17  struct vtpm_state {
   46.18  	struct transmission *current_request;
   46.19  	spinlock_t           req_list_lock;
   46.20 @@ -30,8 +20,6 @@ struct vtpm_state {
   46.21  
   46.22  	unsigned long        disconnect_time;
   46.23  
   46.24 -	struct tpm_virtual_device *tpmvd;
   46.25 -
   46.26  	/*
   46.27  	 * The following is a private structure of the underlying
   46.28  	 * driver. It is passed as parameter in the send function.
   46.29 @@ -51,7 +39,6 @@ int vtpm_vd_send(struct tpm_private * tp
   46.30  
   46.31  /* these functions are offered by tpm_vtpm.c */
   46.32  struct tpm_chip *init_vtpm(struct device *,
   46.33 -                           struct tpm_virtual_device *,
   46.34                             struct tpm_private *);
   46.35  void cleanup_vtpm(struct device *);
   46.36  int vtpm_vd_recv(const struct tpm_chip* chip,
    47.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c	Wed Mar 21 17:03:00 2007 -0500
    47.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c	Wed Mar 21 18:08:31 2007 -0500
    47.3 @@ -369,10 +369,6 @@ static void backend_changed(struct xenbu
    47.4  	}
    47.5  }
    47.6  
    47.7 -struct tpm_virtual_device tvd = {
    47.8 -	.max_tx_size = PAGE_SIZE * TPMIF_TX_RING_SIZE,
    47.9 -};
   47.10 -
   47.11  static int tpmfront_probe(struct xenbus_device *dev,
   47.12                            const struct xenbus_device_id *id)
   47.13  {
   47.14 @@ -383,7 +379,7 @@ static int tpmfront_probe(struct xenbus_
   47.15  	if (!tp)
   47.16  		return -ENOMEM;
   47.17  
   47.18 -	tp->chip = init_vtpm(&dev->dev, &tvd, tp);
   47.19 +	tp->chip = init_vtpm(&dev->dev, tp);
   47.20  	if (IS_ERR(tp->chip))
   47.21  		return PTR_ERR(tp->chip);
   47.22  
   47.23 @@ -500,11 +496,6 @@ static void __init init_tpm_xenbus(void)
   47.24  	xenbus_register_frontend(&tpmfront);
   47.25  }
   47.26  
   47.27 -static void __exit exit_tpm_xenbus(void)
   47.28 -{
   47.29 -	xenbus_unregister_driver(&tpmfront);
   47.30 -}
   47.31 -
   47.32  static int tpmif_allocate_tx_buffers(struct tpm_private *tp)
   47.33  {
   47.34  	unsigned int i;
   47.35 @@ -530,13 +521,11 @@ static void tpmif_free_tx_buffers(struct
   47.36  static void tpmif_rx_action(unsigned long priv)
   47.37  {
   47.38  	struct tpm_private *tp = (struct tpm_private *)priv;
   47.39 -
   47.40  	int i = 0;
   47.41  	unsigned int received;
   47.42  	unsigned int offset = 0;
   47.43  	u8 *buffer;
   47.44 -	tpmif_tx_request_t *tx;
   47.45 -	tx = &tp->tx->ring[i].req;
   47.46 +	tpmif_tx_request_t *tx = &tp->tx->ring[i].req;
   47.47  
   47.48  	atomic_set(&tp->tx_busy, 0);
   47.49  	wake_up_interruptible(&tp->wait_q);
   47.50 @@ -545,7 +534,7 @@ static void tpmif_rx_action(unsigned lon
   47.51  
   47.52  	buffer = kmalloc(received, GFP_ATOMIC);
   47.53  	if (!buffer)
   47.54 -		goto exit;
   47.55 +		return;
   47.56  
   47.57  	for (i = 0; i < TPMIF_TX_RING_SIZE && offset < received; i++) {
   47.58  		struct tx_buffer *txb = tp->tx_buffers[i];
   47.59 @@ -566,10 +555,6 @@ static void tpmif_rx_action(unsigned lon
   47.60  
   47.61  	vtpm_vd_recv(tp->chip, buffer, received, tp->tx_remember);
   47.62  	kfree(buffer);
   47.63 -
   47.64 -exit:
   47.65 -
   47.66 -	return;
   47.67  }
   47.68  
   47.69  
   47.70 @@ -730,13 +715,6 @@ static int __init tpmif_init(void)
   47.71  }
   47.72  
   47.73  
   47.74 -void __exit tpmif_exit(void)
   47.75 -{
   47.76 -	exit_tpm_xenbus();
   47.77 -	tpm_private_put();
   47.78 -	gnttab_free_grant_references(gref_head);
   47.79 -}
   47.80 -
   47.81  module_init(tpmif_init);
   47.82  
   47.83  MODULE_LICENSE("Dual BSD/GPL");
    48.1 --- a/linux-2.6-xen-sparse/drivers/xen/Kconfig	Wed Mar 21 17:03:00 2007 -0500
    48.2 +++ b/linux-2.6-xen-sparse/drivers/xen/Kconfig	Wed Mar 21 18:08:31 2007 -0500
    48.3 @@ -13,7 +13,7 @@ config XEN
    48.4  if XEN
    48.5  config XEN_INTERFACE_VERSION
    48.6  	hex
    48.7 -	default 0x00030203
    48.8 +	default 0x00030205
    48.9  
   48.10  menu "XEN"
   48.11  
   48.12 @@ -227,6 +227,9 @@ choice
   48.13  	config XEN_COMPAT_030002_AND_LATER
   48.14  		bool "3.0.2 and later"
   48.15  
   48.16 +	config XEN_COMPAT_030004_AND_LATER
   48.17 +		bool "3.0.4 and later"
   48.18 +
   48.19  	config XEN_COMPAT_LATEST_ONLY
   48.20  		bool "no compatibility code"
   48.21  
   48.22 @@ -236,6 +239,10 @@ config XEN_COMPAT_030002
   48.23  	bool
   48.24  	default XEN_COMPAT_030002_AND_LATER
   48.25  
   48.26 +config XEN_COMPAT_030004
   48.27 +	bool
   48.28 +	default XEN_COMPAT_030002_AND_LATER || XEN_COMPAT_030004_AND_LATER
   48.29 +
   48.30  endmenu
   48.31  
   48.32  config HAVE_IRQ_IGNORE_UNHANDLED
    49.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c	Wed Mar 21 17:03:00 2007 -0500
    49.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c	Wed Mar 21 18:08:31 2007 -0500
    49.3 @@ -299,7 +299,9 @@ static void tap_backend_changed(struct x
    49.4  	 * and disk info to xenstore
    49.5  	 */
    49.6  	err = xenbus_gather(XBT_NIL, dev->nodename, "info", "%lu", &info, 
    49.7 -			    NULL);	
    49.8 +			    NULL);
    49.9 +	if (XENBUS_EXIST_ERR(err))
   49.10 +		return;
   49.11  	if (err) {
   49.12  		xenbus_dev_error(dev, err, "getting info");
   49.13  		return;
    50.1 --- a/linux-2.6-xen-sparse/drivers/xen/char/mem.c	Wed Mar 21 17:03:00 2007 -0500
    50.2 +++ b/linux-2.6-xen-sparse/drivers/xen/char/mem.c	Wed Mar 21 18:08:31 2007 -0500
    50.3 @@ -27,7 +27,7 @@
    50.4  #include <asm/hypervisor.h>
    50.5  
    50.6  #ifndef ARCH_HAS_VALID_PHYS_ADDR_RANGE
    50.7 -static inline int valid_phys_addr_range(unsigned long addr, size_t *count)
    50.8 +static inline int valid_phys_addr_range(unsigned long addr, size_t count)
    50.9  {
   50.10  	return 1;
   50.11  }
   50.12 @@ -44,7 +44,7 @@ static ssize_t read_mem(struct file * fi
   50.13  	ssize_t read = 0, sz;
   50.14  	void __iomem *v;
   50.15  
   50.16 -	if (!valid_phys_addr_range(p, &count))
   50.17 +	if (!valid_phys_addr_range(p, count))
   50.18  		return -EFAULT;
   50.19  
   50.20  	while (count > 0) {
   50.21 @@ -95,7 +95,7 @@ static ssize_t write_mem(struct file * f
   50.22  	ssize_t written = 0, sz;
   50.23  	void __iomem *v;
   50.24  
   50.25 -	if (!valid_phys_addr_range(p, &count))
   50.26 +	if (!valid_phys_addr_range(p, count))
   50.27  		return -EFAULT;
   50.28  
   50.29  	while (count > 0) {
    51.1 --- a/linux-2.6-xen-sparse/drivers/xen/console/console.c	Wed Mar 21 17:03:00 2007 -0500
    51.2 +++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c	Wed Mar 21 18:08:31 2007 -0500
    51.3 @@ -348,8 +348,11 @@ void xencons_rx(char *buf, unsigned len,
    51.4  #ifdef CONFIG_MAGIC_SYSRQ
    51.5  		if (sysrq_enabled) {
    51.6  			if (buf[i] == '\x0f') { /* ^O */
    51.7 -				sysrq_requested = jiffies;
    51.8 -				continue; /* don't print the sysrq key */
    51.9 +				if (!sysrq_requested) {
   51.10 +					sysrq_requested = jiffies;
   51.11 +					continue; /* don't print sysrq key */
   51.12 +				}
   51.13 +				sysrq_requested = 0;
   51.14  			} else if (sysrq_requested) {
   51.15  				unsigned long sysrq_timeout =
   51.16  					sysrq_requested + HZ*2;
    52.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c	Wed Mar 21 17:03:00 2007 -0500
    52.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c	Wed Mar 21 18:08:31 2007 -0500
    52.3 @@ -11,7 +11,6 @@
    52.4  #include <asm/mmu_context.h>
    52.5  #include <xen/evtchn.h>
    52.6  #include <asm/hypervisor.h>
    52.7 -#include <xen/interface/dom0_ops.h>
    52.8  #include <xen/xenbus.h>
    52.9  #include <linux/cpu.h>
   52.10  #include <linux/kthread.h>
   52.11 @@ -85,7 +84,7 @@ static void post_suspend(int suspend_can
   52.12  			pfn_to_mfn(xen_start_info->console.domU.mfn);
   52.13  	} else {
   52.14  #ifdef CONFIG_SMP
   52.15 -		cpu_initialized_map = cpumask_of_cpu(0);
   52.16 +		cpu_initialized_map = cpu_online_map;
   52.17  #endif
   52.18  	}
   52.19  
   52.20 @@ -181,20 +180,6 @@ static int take_machine_down(void *p_fas
   52.21  	time_resume();
   52.22  	local_irq_enable();
   52.23  
   52.24 -	if (fast_suspend && !suspend_cancelled) {
   52.25 -		/*
   52.26 -		 * In fast-suspend mode the APs may not be brought back online
   52.27 -		 * when we resume. In that case we do it here.
   52.28 -		 */
   52.29 -		for_each_online_cpu(cpu) {
   52.30 -			if (cpu == 0)
   52.31 -				continue;
   52.32 -			cpu_set_initialized(cpu);
   52.33 -			err = HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL);
   52.34 -			BUG_ON(err);
   52.35 -		}
   52.36 -	}
   52.37 -
   52.38  	return suspend_cancelled;
   52.39  }
   52.40  
    53.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Wed Mar 21 17:03:00 2007 -0500
    53.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Wed Mar 21 18:08:31 2007 -0500
    53.3 @@ -110,6 +110,7 @@ static unsigned int alloc_index = 0;
    53.4  
    53.5  static inline unsigned long alloc_mfn(void)
    53.6  {
    53.7 +	BUG_ON(alloc_index == 0);
    53.8  	return mfn_list[--alloc_index];
    53.9  }
   53.10  
   53.11 @@ -552,6 +553,7 @@ static void net_rx_action(unsigned long 
   53.12  		*(int *)skb->cb = nr_frags;
   53.13  
   53.14  		if (!xen_feature(XENFEAT_auto_translated_physmap) &&
   53.15 +		    !((netif_t *)netdev_priv(skb->dev))->copying_receiver &&
   53.16  		    check_mfn(nr_frags + 1)) {
   53.17  			/* Memory squeeze? Back off for an arbitrary while. */
   53.18  			if ( net_ratelimit() )
   53.19 @@ -1265,7 +1267,7 @@ static void net_tx_action(unsigned long 
   53.20  
   53.21  		/* Check the remap error code. */
   53.22  		if (unlikely(netbk_tx_check_mop(skb, &mop))) {
   53.23 -			printk(KERN_ALERT "#### netback grant fails\n");
   53.24 +			DPRINTK("netback grant failed.\n");
   53.25  			skb_shinfo(skb)->nr_frags = 0;
   53.26  			kfree_skb(skb);
   53.27  			continue;
    54.1 --- a/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space.c	Wed Mar 21 17:03:00 2007 -0500
    54.2 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space.c	Wed Mar 21 18:08:31 2007 -0500
    54.3 @@ -349,17 +349,13 @@ void pciback_config_free_dev(struct pci_
    54.4  
    54.5  int pciback_config_add_field_offset(struct pci_dev *dev,
    54.6  				    struct config_field *field,
    54.7 -				    unsigned int offset)
    54.8 +				    unsigned int base_offset)
    54.9  {
   54.10  	int err = 0;
   54.11  	struct pciback_dev_data *dev_data = pci_get_drvdata(dev);
   54.12  	struct config_field_entry *cfg_entry;
   54.13  	void *tmp;
   54.14  
   54.15 -	/* silently ignore duplicate fields */
   54.16 -	if (pciback_field_is_dup(dev, field->offset))
   54.17 -		goto out;
   54.18 -
   54.19  	cfg_entry = kmalloc(sizeof(*cfg_entry), GFP_KERNEL);
   54.20  	if (!cfg_entry) {
   54.21  		err = -ENOMEM;
   54.22 @@ -368,7 +364,12 @@ int pciback_config_add_field_offset(stru
   54.23  
   54.24  	cfg_entry->data = NULL;
   54.25  	cfg_entry->field = field;
   54.26 -	cfg_entry->base_offset = offset;
   54.27 +	cfg_entry->base_offset = base_offset;
   54.28 +
   54.29 +	/* silently ignore duplicate fields */
   54.30 +	err = pciback_field_is_dup(dev,OFFSET(cfg_entry));
   54.31 +	if (err)
   54.32 +		goto out;
   54.33  
   54.34  	if (field->init) {
   54.35  		tmp = field->init(dev, OFFSET(cfg_entry));
    55.1 --- a/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_quirks.c	Wed Mar 21 17:03:00 2007 -0500
    55.2 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_quirks.c	Wed Mar 21 18:08:31 2007 -0500
    55.3 @@ -32,16 +32,14 @@ static inline void register_quirk(struct
    55.4  	list_add_tail(&quirk->quirks_list, &pciback_quirks);
    55.5  }
    55.6  
    55.7 -int pciback_field_is_dup(struct pci_dev *dev, int reg)
    55.8 +int pciback_field_is_dup(struct pci_dev *dev, unsigned int reg)
    55.9  {
   55.10  	int ret = 0;
   55.11  	struct pciback_dev_data *dev_data = pci_get_drvdata(dev);
   55.12 -	struct config_field *field;
   55.13  	struct config_field_entry *cfg_entry;
   55.14  
   55.15  	list_for_each_entry(cfg_entry, &dev_data->config_fields, list) {
   55.16 -		field = cfg_entry->field;
   55.17 -		if (field->offset == reg) {
   55.18 +		if ( OFFSET(cfg_entry) == reg) {
   55.19  			ret = 1;
   55.20  			break;
   55.21  		}
    56.1 --- a/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_quirks.h	Wed Mar 21 17:03:00 2007 -0500
    56.2 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/conf_space_quirks.h	Wed Mar 21 18:08:31 2007 -0500
    56.3 @@ -30,6 +30,6 @@ void pciback_config_field_free(struct co
    56.4  
    56.5  int pciback_config_quirk_release(struct pci_dev *dev);
    56.6  
    56.7 -int pciback_field_is_dup(struct pci_dev *dev, int reg);
    56.8 +int pciback_field_is_dup(struct pci_dev *dev, unsigned int reg);
    56.9  
   56.10  #endif
    57.1 --- a/linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c	Wed Mar 21 17:03:00 2007 -0500
    57.2 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c	Wed Mar 21 18:08:31 2007 -0500
    57.3 @@ -589,10 +589,6 @@ static int pcistub_reg_add(int domain, i
    57.4  	}
    57.5  	dev = psdev->dev;
    57.6  
    57.7 -	/* check for duplicate field */
    57.8 -	if (pciback_field_is_dup(dev, reg))
    57.9 -		goto out;
   57.10 -
   57.11  	field = kzalloc(sizeof(*field), GFP_ATOMIC);
   57.12  	if (!field) {
   57.13  		err = -ENOMEM;
   57.14 @@ -728,10 +724,10 @@ static ssize_t pcistub_quirk_show(struct
   57.15  			if (count >= PAGE_SIZE)
   57.16  				goto out;
   57.17  
   57.18 -			count += scnprintf(buf + count, PAGE_SIZE -
   57.19 -					   count, "\t\t%08x:%01x:%08x\n",
   57.20 -					   field->offset, field->size,
   57.21 -					   field->mask);
   57.22 +			count += scnprintf(buf + count, PAGE_SIZE - count,
   57.23 +					   "\t\t%08x:%01x:%08x\n",
   57.24 +					   cfg_entry->base_offset + field->offset, 
   57.25 +					   field->size, field->mask);
   57.26  		}
   57.27  	}
   57.28  
    58.1 --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c	Wed Mar 21 17:03:00 2007 -0500
    58.2 +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c	Wed Mar 21 18:08:31 2007 -0500
    58.3 @@ -28,7 +28,6 @@
    58.4  #include <asm/hypervisor.h>
    58.5  #include <xen/public/privcmd.h>
    58.6  #include <xen/interface/xen.h>
    58.7 -#include <xen/interface/dom0_ops.h>
    58.8  #include <xen/xen_proc.h>
    58.9  
   58.10  static struct proc_dir_entry *privcmd_intf;
    59.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c	Wed Mar 21 17:03:00 2007 -0500
    59.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c	Wed Mar 21 18:08:31 2007 -0500
    59.3 @@ -110,7 +110,6 @@ int xb_write(const void *data, unsigned 
    59.4  		/* Read indexes, then verify. */
    59.5  		cons = intf->req_cons;
    59.6  		prod = intf->req_prod;
    59.7 -		mb();
    59.8  		if (!check_indexes(cons, prod)) {
    59.9  			intf->req_cons = intf->req_prod = 0;
   59.10  			return -EIO;
   59.11 @@ -122,15 +121,18 @@ int xb_write(const void *data, unsigned 
   59.12  		if (avail > len)
   59.13  			avail = len;
   59.14  
   59.15 +		/* Must write data /after/ reading the consumer index. */
   59.16 +		mb();
   59.17 +
   59.18  		memcpy(dst, data, avail);
   59.19  		data += avail;
   59.20  		len -= avail;
   59.21  
   59.22 -		/* Other side must not see new header until data is there. */
   59.23 +		/* Other side must not see new producer until data is there. */
   59.24  		wmb();
   59.25  		intf->req_prod += avail;
   59.26  
   59.27 -		/* This implies mb() before other side sees interrupt. */
   59.28 +		/* Implies mb(): other side will see the updated producer. */
   59.29  		notify_remote_via_evtchn(xen_store_evtchn);
   59.30  	}
   59.31  
   59.32 @@ -165,7 +167,6 @@ int xb_read(void *data, unsigned len)
   59.33  		/* Read indexes, then verify. */
   59.34  		cons = intf->rsp_cons;
   59.35  		prod = intf->rsp_prod;
   59.36 -		mb();
   59.37  		if (!check_indexes(cons, prod)) {
   59.38  			intf->rsp_cons = intf->rsp_prod = 0;
   59.39  			return -EIO;
   59.40 @@ -177,7 +178,7 @@ int xb_read(void *data, unsigned len)
   59.41  		if (avail > len)
   59.42  			avail = len;
   59.43  
   59.44 -		/* We must read header before we read data. */
   59.45 +		/* Must read data /after/ reading the producer index. */
   59.46  		rmb();
   59.47  
   59.48  		memcpy(data, src, avail);
   59.49 @@ -190,7 +191,7 @@ int xb_read(void *data, unsigned len)
   59.50  
   59.51  		pr_debug("Finished read of %i bytes (%i to go)\n", avail, len);
   59.52  
   59.53 -		/* Implies mb(): they will see new header. */
   59.54 +		/* Implies mb(): other side will see the updated consumer. */
   59.55  		notify_remote_via_evtchn(xen_store_evtchn);
   59.56  	}
   59.57  
    60.1 --- a/linux-2.6-xen-sparse/include/asm-i386/kexec.h	Wed Mar 21 17:03:00 2007 -0500
    60.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/kexec.h	Wed Mar 21 18:08:31 2007 -0500
    60.3 @@ -47,6 +47,9 @@
    60.4  /* The native architecture */
    60.5  #define KEXEC_ARCH KEXEC_ARCH_386
    60.6  
    60.7 +/* We can also handle crash dumps from 64 bit kernel. */
    60.8 +#define vmcore_elf_check_arch_cross(x) ((x)->e_machine == EM_X86_64)
    60.9 +
   60.10  #define MAX_NOTE_BYTES 1024
   60.11  
   60.12  /* CPU does not save ss and esp on stack if execution is already
    61.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h	Wed Mar 21 17:03:00 2007 -0500
    61.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h	Wed Mar 21 18:08:31 2007 -0500
    61.3 @@ -201,11 +201,11 @@ HYPERVISOR_set_timer_op(
    61.4  }
    61.5  
    61.6  static inline int
    61.7 -HYPERVISOR_dom0_op(
    61.8 -	dom0_op_t *dom0_op)
    61.9 +HYPERVISOR_platform_op(
   61.10 +	struct xen_platform_op *platform_op)
   61.11  {
   61.12 -	dom0_op->interface_version = DOM0_INTERFACE_VERSION;
   61.13 -	return _hypercall1(int, dom0_op, dom0_op);
   61.14 +	platform_op->interface_version = XENPF_INTERFACE_VERSION;
   61.15 +	return _hypercall1(int, platform_op, platform_op);
   61.16  }
   61.17  
   61.18  static inline int
    62.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h	Wed Mar 21 17:03:00 2007 -0500
    62.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h	Wed Mar 21 18:08:31 2007 -0500
    62.3 @@ -38,7 +38,7 @@
    62.4  #include <linux/version.h>
    62.5  #include <linux/errno.h>
    62.6  #include <xen/interface/xen.h>
    62.7 -#include <xen/interface/dom0_ops.h>
    62.8 +#include <xen/interface/platform.h>
    62.9  #include <xen/interface/event_channel.h>
   62.10  #include <xen/interface/physdev.h>
   62.11  #include <xen/interface/sched.h>
    63.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pci.h	Wed Mar 21 17:03:00 2007 -0500
    63.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pci.h	Wed Mar 21 18:08:31 2007 -0500
    63.3 @@ -143,11 +143,4 @@ static inline void pci_dma_burst_advice(
    63.4  /* generic pci stuff */
    63.5  #include <asm-generic/pci.h>
    63.6  
    63.7 -/* On Xen we have to scan all functions since Xen hides bridges from
    63.8 - * us.  If a bridge is at fn=0 and that slot has a multifunction
    63.9 - * device, we won't find the additional devices without scanning all
   63.10 - * functions. */
   63.11 -#undef pcibios_scan_all_fns
   63.12 -#define pcibios_scan_all_fns(a, b)	1
   63.13 -
   63.14  #endif /* __i386_PCI_H */
    64.1 --- a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h	Wed Mar 21 17:03:00 2007 -0500
    64.2 +++ b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h	Wed Mar 21 18:08:31 2007 -0500
    64.3 @@ -120,9 +120,9 @@ HYPERVISOR_set_timer_op(u64 timeout)
    64.4  }
    64.5  
    64.6  static inline int
    64.7 -xencomm_arch_hypercall_dom0_op(struct xencomm_handle *op)
    64.8 +xencomm_arch_hypercall_platform_op(struct xencomm_handle *op)
    64.9  {
   64.10 -	return _hypercall1(int, dom0_op, op);
   64.11 +	return _hypercall1(int, platform_op, op);
   64.12  }
   64.13  
   64.14  static inline int
    65.1 --- a/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h	Wed Mar 21 17:03:00 2007 -0500
    65.2 +++ b/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h	Wed Mar 21 18:08:31 2007 -0500
    65.3 @@ -51,7 +51,7 @@ extern int running_on_xen;
    65.4  #include <linux/version.h>
    65.5  #include <linux/errno.h>
    65.6  #include <xen/interface/xen.h>
    65.7 -#include <xen/interface/dom0_ops.h>
    65.8 +#include <xen/interface/platform.h>
    65.9  #include <xen/interface/event_channel.h>
   65.10  #include <xen/interface/physdev.h>
   65.11  #include <xen/interface/sched.h>
    66.1 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h	Wed Mar 21 17:03:00 2007 -0500
    66.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h	Wed Mar 21 18:08:31 2007 -0500
    66.3 @@ -204,11 +204,11 @@ HYPERVISOR_set_timer_op(
    66.4  }
    66.5  
    66.6  static inline int
    66.7 -HYPERVISOR_dom0_op(
    66.8 -	dom0_op_t *dom0_op)
    66.9 +HYPERVISOR_platform_op(
   66.10 +	struct xen_platform_op *platform_op)
   66.11  {
   66.12 -	dom0_op->interface_version = DOM0_INTERFACE_VERSION;
   66.13 -	return _hypercall1(int, dom0_op, dom0_op);
   66.14 +	platform_op->interface_version = XENPF_INTERFACE_VERSION;
   66.15 +	return _hypercall1(int, platform_op, platform_op);
   66.16  }
   66.17  
   66.18  static inline int
    67.1 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pci.h	Wed Mar 21 17:03:00 2007 -0500
    67.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pci.h	Wed Mar 21 18:08:31 2007 -0500
    67.3 @@ -163,11 +163,4 @@ static inline void pcibios_add_platform_
    67.4  #include <asm-generic/pci.h>
    67.5  #endif
    67.6  
    67.7 -/* On Xen we have to scan all functions since Xen hides bridges from
    67.8 - * us.  If a bridge is at fn=0 and that slot has a multifunction
    67.9 - * device, we won't find the additional devices without scanning all
   67.10 - * functions. */
   67.11 -#undef pcibios_scan_all_fns
   67.12 -#define pcibios_scan_all_fns(a, b)	1
   67.13 -
   67.14  #endif /* __x8664_PCI_H */
    68.1 --- a/linux-2.6-xen-sparse/kernel/kexec.c	Wed Mar 21 17:03:00 2007 -0500
    68.2 +++ b/linux-2.6-xen-sparse/kernel/kexec.c	Wed Mar 21 18:08:31 2007 -0500
    68.3 @@ -330,13 +330,27 @@ static int kimage_is_destination_range(s
    68.4  	return 0;
    68.5  }
    68.6  
    68.7 -static struct page *kimage_alloc_pages(gfp_t gfp_mask, unsigned int order)
    68.8 +static struct page *kimage_alloc_pages(gfp_t gfp_mask, unsigned int order, unsigned long limit)
    68.9  {
   68.10  	struct page *pages;
   68.11  
   68.12  	pages = alloc_pages(gfp_mask, order);
   68.13  	if (pages) {
   68.14  		unsigned int count, i;
   68.15 +#ifdef CONFIG_XEN
   68.16 +		int address_bits;
   68.17 +
   68.18 +		if (limit == ~0UL)
   68.19 +			address_bits = BITS_PER_LONG;
   68.20 +		else
   68.21 +			address_bits = long_log2(limit);
   68.22 +
   68.23 +		if (xen_create_contiguous_region((unsigned long)page_address(pages),
   68.24 +						 order, address_bits) < 0) {
   68.25 +			__free_pages(pages, order);
   68.26 +			return NULL;
   68.27 +		}
   68.28 +#endif
   68.29  		pages->mapping = NULL;
   68.30  		set_page_private(pages, order);
   68.31  		count = 1 << order;
   68.32 @@ -355,6 +369,9 @@ static void kimage_free_pages(struct pag
   68.33  	count = 1 << order;
   68.34  	for (i = 0; i < count; i++)
   68.35  		ClearPageReserved(page + i);
   68.36 +#ifdef CONFIG_XEN
   68.37 +	xen_destroy_contiguous_region((unsigned long)page_address(page), order);
   68.38 +#endif
   68.39  	__free_pages(page, order);
   68.40  }
   68.41  
   68.42 @@ -400,7 +417,7 @@ static struct page *kimage_alloc_normal_
   68.43  	do {
   68.44  		unsigned long pfn, epfn, addr, eaddr;
   68.45  
   68.46 -		pages = kimage_alloc_pages(GFP_KERNEL, order);
   68.47 +		pages = kimage_alloc_pages(GFP_KERNEL, order, KEXEC_CONTROL_MEMORY_LIMIT);
   68.48  		if (!pages)
   68.49  			break;
   68.50  		pfn   = kexec_page_to_pfn(pages);
   68.51 @@ -709,7 +726,7 @@ static struct page *kimage_alloc_page(st
   68.52  		kimage_entry_t *old;
   68.53  
   68.54  		/* Allocate a page, if we run out of memory give up */
   68.55 -		page = kimage_alloc_pages(gfp_mask, 0);
   68.56 +		page = kimage_alloc_pages(gfp_mask, 0, KEXEC_SOURCE_MEMORY_LIMIT);
   68.57  		if (!page)
   68.58  			return NULL;
   68.59  		/* If the page cannot be used file it away */
    69.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    69.2 +++ b/linux-2.6-xen-sparse/mm/Kconfig	Wed Mar 21 18:08:31 2007 -0500
    69.3 @@ -0,0 +1,157 @@
    69.4 +config SELECT_MEMORY_MODEL
    69.5 +	def_bool y
    69.6 +	depends on EXPERIMENTAL || ARCH_SELECT_MEMORY_MODEL
    69.7 +
    69.8 +choice
    69.9 +	prompt "Memory model"
   69.10 +	depends on SELECT_MEMORY_MODEL
   69.11 +	default DISCONTIGMEM_MANUAL if ARCH_DISCONTIGMEM_DEFAULT
   69.12 +	default SPARSEMEM_MANUAL if ARCH_SPARSEMEM_DEFAULT
   69.13 +	default FLATMEM_MANUAL
   69.14 +
   69.15 +config FLATMEM_MANUAL
   69.16 +	bool "Flat Memory"
   69.17 +	depends on !(ARCH_DISCONTIGMEM_ENABLE || ARCH_SPARSEMEM_ENABLE) || ARCH_FLATMEM_ENABLE
   69.18 +	help
   69.19 +	  This option allows you to change some of the ways that
   69.20 +	  Linux manages its memory internally.  Most users will
   69.21 +	  only have one option here: FLATMEM.  This is normal
   69.22 +	  and a correct option.
   69.23 +
   69.24 +	  Some users of more advanced features like NUMA and
   69.25 +	  memory hotplug may have different options here.
   69.26 +	  DISCONTIGMEM is an more mature, better tested system,
   69.27 +	  but is incompatible with memory hotplug and may suffer
   69.28 +	  decreased performance over SPARSEMEM.  If unsure between
   69.29 +	  "Sparse Memory" and "Discontiguous Memory", choose
   69.30 +	  "Discontiguous Memory".
   69.31 +
   69.32 +	  If unsure, choose this option (Flat Memory) over any other.
   69.33 +
   69.34 +config DISCONTIGMEM_MANUAL
   69.35 +	bool "Discontiguous Memory"
   69.36 +	depends on ARCH_DISCONTIGMEM_ENABLE
   69.37 +	help
   69.38 +	  This option provides enhanced support for discontiguous
   69.39 +	  memory systems, over FLATMEM.  These systems have holes
   69.40 +	  in their physical address spaces, and this option provides
   69.41 +	  more efficient handling of these holes.  However, the vast
   69.42 +	  majority of hardware has quite flat address spaces, and
   69.43 +	  can have degraded performance from extra overhead that
   69.44 +	  this option imposes.
   69.45 +
   69.46 +	  Many NUMA configurations will have this as the only option.
   69.47 +
   69.48 +	  If unsure, choose "Flat Memory" over this option.
   69.49 +
   69.50 +config SPARSEMEM_MANUAL
   69.51 +	bool "Sparse Memory"
   69.52 +	depends on ARCH_SPARSEMEM_ENABLE
   69.53 +	help
   69.54 +	  This will be the only option for some systems, including
   69.55 +	  memory hotplug systems.  This is normal.
   69.56 +
   69.57 +	  For many other systems, this will be an alternative to
   69.58 +	  "Discontiguous Memory".  This option provides some potential
   69.59 +	  performance benefits, along with decreased code complexity,
   69.60 +	  but it is newer, and more experimental.
   69.61 +
   69.62 +	  If unsure, choose "Discontiguous Memory" or "Flat Memory"
   69.63 +	  over this option.
   69.64 +
   69.65 +endchoice
   69.66 +
   69.67 +config DISCONTIGMEM
   69.68 +	def_bool y
   69.69 +	depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL
   69.70 +
   69.71 +config SPARSEMEM
   69.72 +	def_bool y
   69.73 +	depends on SPARSEMEM_MANUAL
   69.74 +
   69.75 +config FLATMEM
   69.76 +	def_bool y
   69.77 +	depends on (!DISCONTIGMEM && !SPARSEMEM) || FLATMEM_MANUAL
   69.78 +
   69.79 +config FLAT_NODE_MEM_MAP
   69.80 +	def_bool y
   69.81 +	depends on !SPARSEMEM
   69.82 +
   69.83 +#
   69.84 +# Both the NUMA code and DISCONTIGMEM use arrays of pg_data_t's
   69.85 +# to represent different areas of memory.  This variable allows
   69.86 +# those dependencies to exist individually.
   69.87 +#
   69.88 +config NEED_MULTIPLE_NODES
   69.89 +	def_bool y
   69.90 +	depends on DISCONTIGMEM || NUMA
   69.91 +
   69.92 +config HAVE_MEMORY_PRESENT
   69.93 +	def_bool y
   69.94 +	depends on ARCH_HAVE_MEMORY_PRESENT || SPARSEMEM
   69.95 +
   69.96 +#
   69.97 +# SPARSEMEM_EXTREME (which is the default) does some bootmem
   69.98 +# allocations when memory_present() is called.  If this can not
   69.99 +# be done on your architecture, select this option.  However,
  69.100 +# statically allocating the mem_section[] array can potentially
  69.101 +# consume vast quantities of .bss, so be careful.
  69.102 +#
  69.103 +# This option will also potentially produce smaller runtime code
  69.104 +# with gcc 3.4 and later.
  69.105 +#
  69.106 +config SPARSEMEM_STATIC
  69.107 +	def_bool n
  69.108 +
  69.109 +#
  69.110 +# Architectecture platforms which require a two level mem_section in SPARSEMEM
  69.111 +# must select this option. This is usually for architecture platforms with
  69.112 +# an extremely sparse physical address space.
  69.113 +#
  69.114 +config SPARSEMEM_EXTREME
  69.115 +	def_bool y
  69.116 +	depends on SPARSEMEM && !SPARSEMEM_STATIC
  69.117 +
  69.118 +# eventually, we can have this option just 'select SPARSEMEM'
  69.119 +config MEMORY_HOTPLUG
  69.120 +	bool "Allow for memory hot-add"
  69.121 +	depends on SPARSEMEM && HOTPLUG && !SOFTWARE_SUSPEND && ARCH_ENABLE_MEMORY_HOTPLUG
  69.122 +	depends on (IA64 || X86 || PPC64)
  69.123 +
  69.124 +comment "Memory hotplug is currently incompatible with Software Suspend"
  69.125 +	depends on SPARSEMEM && HOTPLUG && SOFTWARE_SUSPEND
  69.126 +
  69.127 +# Heavily threaded applications may benefit from splitting the mm-wide
  69.128 +# page_table_lock, so that faults on different parts of the user address
  69.129 +# space can be handled with less contention: split it at this NR_CPUS.
  69.130 +# Default to 4 for wider testing, though 8 might be more appropriate.
  69.131 +# ARM's adjust_pte (unused if VIPT) depends on mm-wide page_table_lock.
  69.132 +# PA-RISC 7xxx's spinlock_t would enlarge struct page from 32 to 44 bytes.
  69.133 +# XEN on x86 architecture uses the mapping field on pagetable pages to store a
  69.134 +# pointer to the destructor. This conflicts with pte_lock_deinit().
  69.135 +#
  69.136 +config SPLIT_PTLOCK_CPUS
  69.137 +	int
  69.138 +	default "4096" if ARM && !CPU_CACHE_VIPT
  69.139 +	default "4096" if PARISC && !PA20
  69.140 +	default "4096" if X86_XEN || X86_64_XEN
  69.141 +	default "4"
  69.142 +
  69.143 +#
  69.144 +# support for page migration
  69.145 +#
  69.146 +config MIGRATION
  69.147 +	bool "Page migration"
  69.148 +	def_bool y
  69.149 +	depends on NUMA
  69.150 +	help
  69.151 +	  Allows the migration of the physical location of pages of processes
  69.152 +	  while the virtual addresses are not changed. This is useful for
  69.153 +	  example on NUMA systems to put pages nearer to the processors accessing
  69.154 +	  the page.
  69.155 +
  69.156 +config RESOURCES_64BIT
  69.157 +	bool "64 bit Memory and IO resources (EXPERIMENTAL)" if (!64BIT && EXPERIMENTAL)
  69.158 +	default 64BIT
  69.159 +	help
  69.160 +	  This option allows memory and IO resources to be 64 bit.
    70.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    70.2 +++ b/patches/linux-2.6.18/allow-i386-crash-kernels-to-handle-x86_64-dumps-fix.patch	Wed Mar 21 18:08:31 2007 -0500
    70.3 @@ -0,0 +1,30 @@
    70.4 +From: Andrew Morton <akpm@linux-foundation.org>
    70.5 +
    70.6 +In file included from arch/i386/kernel/setup.c:46:
    70.7 +include/linux/crash_dump.h:19:36: warning: extra tokens at end of #ifndef directive
    70.8 +
    70.9 +Cc: "Eric W. Biederman" <ebiederm@xmission.com>
   70.10 +Cc: Andi Kleen <ak@suse.de>
   70.11 +Cc: Horms <horms@verge.net.au>
   70.12 +Cc: Ian Campbell <ian.campbell@xensource.com>
   70.13 +Cc: Magnus Damm <magnus.damm@gmail.com>
   70.14 +Cc: Vivek Goyal <vgoyal@in.ibm.com>
   70.15 +Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
   70.16 +---
   70.17 +
   70.18 + include/linux/crash_dump.h |    2 +-
   70.19 + 1 file changed, 1 insertion(+), 1 deletion(-)
   70.20 +
   70.21 +diff -puN include/linux/crash_dump.h~allow-i386-crash-kernels-to-handle-x86_64-dumps-fix include/linux/crash_dump.h
   70.22 +--- a/include/linux/crash_dump.h~allow-i386-crash-kernels-to-handle-x86_64-dumps-fix
   70.23 ++++ a/include/linux/crash_dump.h
   70.24 +@@ -16,7 +16,7 @@ extern struct proc_dir_entry *proc_vmcor
   70.25 + 
   70.26 + /* Architecture code defines this if there are other possible ELF
   70.27 +  * machine types, e.g. on bi-arch capable hardware. */
   70.28 +-#ifndef vmcore_elf_check_arch_cross(x)
   70.29 ++#ifndef vmcore_elf_check_arch_cross
   70.30 + #define vmcore_elf_check_arch_cross(x) 0
   70.31 + #endif
   70.32 + 
   70.33 +_
    71.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    71.2 +++ b/patches/linux-2.6.18/allow-i386-crash-kernels-to-handle-x86_64-dumps.patch	Wed Mar 21 18:08:31 2007 -0500
    71.3 @@ -0,0 +1,66 @@
    71.4 +From: Ian Campbell <ian.campbell@xensource.com>
    71.5 +
    71.6 +The specific case I am encountering is kdump under Xen with a 64 bit
    71.7 +hypervisor and 32 bit kernel/userspace.  The dump created is 64 bit due to
    71.8 +the hypervisor but the dump kernel is 32 bit for maximum compatibility.
    71.9 +
   71.10 +It's possibly less likely to be useful in a purely native scenario but I
   71.11 +see no reason to disallow it.
   71.12 +
   71.13 +Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
   71.14 +Acked-by: Vivek Goyal <vgoyal@in.ibm.com>
   71.15 +Cc: Horms <horms@verge.net.au>
   71.16 +Cc: Magnus Damm <magnus.damm@gmail.com>
   71.17 +Cc: "Eric W. Biederman" <ebiederm@xmission.com>
   71.18 +Cc: Andi Kleen <ak@suse.de>
   71.19 +Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
   71.20 +---
   71.21 +
   71.22 + fs/proc/vmcore.c           |    2 +-
   71.23 + include/asm-i386/kexec.h   |    3 +++
   71.24 + include/linux/crash_dump.h |    8 ++++++++
   71.25 + 3 files changed, 12 insertions(+), 1 deletion(-)
   71.26 +
   71.27 +diff -puN fs/proc/vmcore.c~allow-i386-crash-kernels-to-handle-x86_64-dumps fs/proc/vmcore.c
   71.28 +--- a/fs/proc/vmcore.c~allow-i386-crash-kernels-to-handle-x86_64-dumps
   71.29 ++++ a/fs/proc/vmcore.c
   71.30 +@@ -514,7 +514,7 @@ static int __init parse_crash_elf64_head
   71.31 + 	/* Do some basic Verification. */
   71.32 + 	if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 ||
   71.33 + 		(ehdr.e_type != ET_CORE) ||
   71.34 +-		!elf_check_arch(&ehdr) ||
   71.35 ++		!vmcore_elf_check_arch(&ehdr) ||
   71.36 + 		ehdr.e_ident[EI_CLASS] != ELFCLASS64 ||
   71.37 + 		ehdr.e_ident[EI_VERSION] != EV_CURRENT ||
   71.38 + 		ehdr.e_version != EV_CURRENT ||
   71.39 +diff -puN include/asm-i386/kexec.h~allow-i386-crash-kernels-to-handle-x86_64-dumps include/asm-i386/kexec.h
   71.40 +--- a/include/asm-i386/kexec.h~allow-i386-crash-kernels-to-handle-x86_64-dumps
   71.41 ++++ a/include/asm-i386/kexec.h
   71.42 +@@ -47,6 +47,9 @@
   71.43 + /* The native architecture */
   71.44 + #define KEXEC_ARCH KEXEC_ARCH_386
   71.45 + 
   71.46 ++/* We can also handle crash dumps from 64 bit kernel. */
   71.47 ++#define vmcore_elf_check_arch_cross(x) ((x)->e_machine == EM_X86_64)
   71.48 ++
   71.49 + #define MAX_NOTE_BYTES 1024
   71.50 + 
   71.51 + /* CPU does not save ss and esp on stack if execution is already
   71.52 +diff -puN include/linux/crash_dump.h~allow-i386-crash-kernels-to-handle-x86_64-dumps include/linux/crash_dump.h
   71.53 +--- a/include/linux/crash_dump.h~allow-i386-crash-kernels-to-handle-x86_64-dumps
   71.54 ++++ a/include/linux/crash_dump.h
   71.55 +@@ -14,5 +14,13 @@ extern ssize_t copy_oldmem_page(unsigned
   71.56 + extern const struct file_operations proc_vmcore_operations;
   71.57 + extern struct proc_dir_entry *proc_vmcore;
   71.58 + 
   71.59 ++/* Architecture code defines this if there are other possible ELF
   71.60 ++ * machine types, e.g. on bi-arch capable hardware. */
   71.61 ++#ifndef vmcore_elf_check_arch_cross(x)
   71.62 ++#define vmcore_elf_check_arch_cross(x) 0
   71.63 ++#endif
   71.64 ++
   71.65 ++#define vmcore_elf_check_arch(x) (elf_check_arch(x) || vmcore_elf_check_arch_cross(x))
   71.66 ++
   71.67 + #endif /* CONFIG_CRASH_DUMP */
   71.68 + #endif /* LINUX_CRASHDUMP_H */
   71.69 +_
    72.1 --- a/patches/linux-2.6.18/series	Wed Mar 21 17:03:00 2007 -0500
    72.2 +++ b/patches/linux-2.6.18/series	Wed Mar 21 18:08:31 2007 -0500
    72.3 @@ -19,3 +19,5 @@ x86-elfnote-as-preprocessor-macro.patch
    72.4  fixaddr-top.patch
    72.5  git-c06cb8b1c4d25e5b4d7a2d7c2462619de1e0dbc4.patch
    72.6  softlockup-no-idle-hz.patch
    72.7 +allow-i386-crash-kernels-to-handle-x86_64-dumps.patch
    72.8 +allow-i386-crash-kernels-to-handle-x86_64-dumps-fix.patch
    73.1 --- a/patches/linux-2.6.18/softlockup-no-idle-hz.patch	Wed Mar 21 17:03:00 2007 -0500
    73.2 +++ b/patches/linux-2.6.18/softlockup-no-idle-hz.patch	Wed Mar 21 18:08:31 2007 -0500
    73.3 @@ -34,7 +34,7 @@ diff -pruN ../orig-linux-2.6.18/kernel/s
    73.4  +			!per_cpu(watchdog_task, this_cpu))
    73.5  +		return MAX_JIFFY_OFFSET;
    73.6  +
    73.7 -+	return min_t(long, 0, touch_timestamp + HZ - jiffies);
    73.8 ++	return max_t(long, 0, touch_timestamp + HZ - jiffies);
    73.9  +}
   73.10  +
   73.11   /*
    74.1 --- a/tools/Rules.mk	Wed Mar 21 17:03:00 2007 -0500
    74.2 +++ b/tools/Rules.mk	Wed Mar 21 18:08:31 2007 -0500
    74.3 @@ -23,6 +23,11 @@ LDFLAGS += $(shell getconf LFS_LDFLAGS)
    74.4  CFLAGS-$(CONFIG_X86_32) += $(call cc-option,$(CC),-mno-tls-direct-seg-refs)
    74.5  CFLAGS += $(CFLAGS-y)
    74.6  
    74.7 +# Require GCC v3.4+ (to avoid issues with alignment constraints in Xen headers)
    74.8 +ifeq ($(CONFIG_X86)$(call cc-ver,$(CC),0x030400),yn)
    74.9 +$(error Xen tools require at least gcc-3.4)
   74.10 +endif
   74.11 +
   74.12  %.opic: %.c
   74.13  	$(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $<
   74.14  
    75.1 --- a/tools/blktap/drivers/block-qcow.c	Wed Mar 21 17:03:00 2007 -0500
    75.2 +++ b/tools/blktap/drivers/block-qcow.c	Wed Mar 21 18:08:31 2007 -0500
    75.3 @@ -1057,6 +1057,7 @@ int tdqcow_queue_write(struct disk_drive
    75.4  						    index_in_cluster+n);
    75.5  		if (!cluster_offset) {
    75.6  			DPRINTF("Ooops, no write cluster offset!\n");
    75.7 +			aio_unlock(s, sector);
    75.8  			return cb(dd, -EIO, sector, nb_sectors, id, private);
    75.9  		}
   75.10  
    76.1 --- a/tools/firmware/Makefile	Wed Mar 21 17:03:00 2007 -0500
    76.2 +++ b/tools/firmware/Makefile	Wed Mar 21 18:08:31 2007 -0500
    76.3 @@ -14,10 +14,10 @@ SUBDIRS += hvmloader
    76.4  
    76.5  .PHONY: all
    76.6  all:
    76.7 -	@set -e; if ! `which bcc 1>/dev/null 2>/dev/null`; then \
    76.8 +	@set -e; if [ $$((`( bcc -v 2>&1 | grep version || echo 0.0.0 ) | cut -d' ' -f 3 | awk -F. '{ printf "0x%02x%02x%02x", $$1, $$2, $$3}'`)) -lt $$((0x00100e)) ] ; then \
    76.9  	echo "***********************************************************"; \
   76.10 -	echo "WARNING: Install dev86 package to build firmware!"; \
   76.11 -	echo "         (http://www.cix.co.uk/~mayday)"; \
   76.12 +	echo "Require dev86 package version >= 0.16.14 to build firmware!"; \
   76.13 +	echo "(visit http://www.cix.co.uk/~mayday for more information)"; \
   76.14  	echo "***********************************************************"; \
   76.15  	else \
   76.16  	for subdir in $(SUBDIRS); do \
    77.1 --- a/tools/firmware/hvmloader/32bitbios_support.c	Wed Mar 21 17:03:00 2007 -0500
    77.2 +++ b/tools/firmware/hvmloader/32bitbios_support.c	Wed Mar 21 18:08:31 2007 -0500
    77.3 @@ -17,158 +17,129 @@
    77.4   * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
    77.5   * Place - Suite 330, Boston, MA 02111-1307 USA.
    77.6   */
    77.7 +
    77.8  #include <inttypes.h>
    77.9  #include <elf.h>
   77.10  #ifdef __sun__
   77.11  #include <sys/machelf.h>
   77.12  #endif
   77.13  
   77.14 -#include <xen/hvm/e820.h>
   77.15  #include "util.h"
   77.16  #include "config.h"
   77.17  
   77.18  #include "../rombios/32bit/32bitbios_flat.h"
   77.19  #include "../rombios/32bit/jumptable.h"
   77.20  
   77.21 -
   77.22 -/*
   77.23 - * relocate ELF file of type ET_REL
   77.24 - */
   77.25 -static int relocate_elf(unsigned char *elfarray) {
   77.26 +/* Relocate ELF file of type ET_REL */
   77.27 +static void relocate_elf(char *elfarray)
   77.28 +{
   77.29      Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfarray;
   77.30      Elf32_Shdr *shdr = (Elf32_Shdr *)&elfarray[ehdr->e_shoff];
   77.31 -    int i;
   77.32 -
   77.33 -    if (ehdr->e_type != ET_REL) {
   77.34 -        printf("Not a relocatable BIOS object file. Has type %d, need %d\n",
   77.35 -               ehdr->e_type, ET_REL);
   77.36 -        return -1;
   77.37 -    }
   77.38 +    Elf32_Sym  *syms, *sym;
   77.39 +    Elf32_Rel  *rels;
   77.40 +    char       *code;
   77.41 +    uint32_t   *loc, fix;
   77.42 +    int i, j;
   77.43  
   77.44 -    for (i = 0; i < ehdr->e_shnum; i++) {
   77.45 -        if (!(shdr[i]).sh_flags & SHF_ALLOC) {
   77.46 -            shdr[i].sh_addr = 0;
   77.47 +    for ( i = 0; i < ehdr->e_shnum; i++ )
   77.48 +        shdr[i].sh_addr = (Elf32_Addr)&elfarray[shdr[i].sh_offset];
   77.49 +
   77.50 +    for ( i = 0; i < ehdr->e_shnum; i++ )
   77.51 +    {
   77.52 +        if ( shdr[i].sh_type == SHT_RELA )
   77.53 +            printf("Unsupported section type SHT_RELA\n");
   77.54 +
   77.55 +        if ( shdr[i].sh_type != SHT_REL )
   77.56              continue;
   77.57 -        }
   77.58 -        shdr[i].sh_addr = (Elf32_Addr)&elfarray[shdr[i].sh_offset];
   77.59 -    }
   77.60  
   77.61 -    for (i = 0; i < ehdr->e_shnum; i++) {
   77.62 -        if (shdr[i].sh_type == SHT_REL && shdr[i].sh_addr != 0) {
   77.63 -            Elf32_Shdr *targetsec = (Elf32_Shdr *)&(shdr[shdr[i].sh_info]);
   77.64 -            Elf32_Shdr *symtabsec = (Elf32_Shdr *)&(shdr[shdr[i].sh_link]);
   77.65 -            Elf32_Sym  *syms      = (Elf32_Sym *)symtabsec->sh_addr;
   77.66 -            Elf32_Rel  *rels      = (Elf32_Rel *)shdr[i].sh_addr;
   77.67 -            unsigned char *code   = (unsigned char *)targetsec->sh_addr;
   77.68 -            int j;
   77.69 +        syms = (Elf32_Sym *)shdr[shdr[i].sh_link].sh_addr;
   77.70 +        rels = (Elf32_Rel *)shdr[i].sh_addr;
   77.71 +        code = (char      *)shdr[shdr[i].sh_info].sh_addr;
   77.72 +
   77.73 +        for ( j = 0; j < shdr[i].sh_size / sizeof(Elf32_Rel); j++ )
   77.74 +        {
   77.75 +            sym = &syms[ELF32_R_SYM(rels[j].r_info)];
   77.76 +            loc = (uint32_t *)&code[rels[j].r_offset];
   77.77 +            fix = shdr[sym->st_shndx].sh_addr + sym->st_value;
   77.78  
   77.79 -            for (j = 0; j < shdr[i].sh_size / sizeof(Elf32_Rel); j++) {
   77.80 -                int idx           = ELF32_R_SYM(rels[j].r_info);
   77.81 -                Elf32_Sym *symbol = &syms[idx];
   77.82 -                uint32_t *loc     = (uint32_t *)&code[rels[j].r_offset];
   77.83 -                uint32_t fix      = shdr[symbol->st_shndx].sh_addr +
   77.84 -                                    symbol->st_value;
   77.85 +            switch ( ELF32_R_TYPE(rels[j].r_info) )
   77.86 +            {
   77.87 +            case R_386_PC32:
   77.88 +                *loc += fix - (uint32_t)loc;
   77.89 +                break;
   77.90  
   77.91 -                switch (ELF32_R_TYPE(rels[j].r_info)) {
   77.92 -                    case R_386_PC32:
   77.93 -                        *loc += (fix - (uint32_t)loc);
   77.94 -                    break;
   77.95 -
   77.96 -                    case R_386_32:
   77.97 -                        *loc += fix;
   77.98 -                    break;
   77.99 -                }
  77.100 +            case R_386_32:
  77.101 +                *loc += fix;
  77.102 +                break;
  77.103              }
  77.104 -        } else if (shdr[i].sh_type == SHT_RELA) {
  77.105 -            return -2;
  77.106          }
  77.107      }
  77.108 -    return 0;
  77.109  }
  77.110  
  77.111 -/* scan the rombios for the destination of the jumptable */
  77.112 -static char* get_jump_table_start(void)
  77.113 +/* Scan the rombios for the destination of the jump table. */
  77.114 +static char *get_jump_table_start(void)
  77.115  {
  77.116      char *bios_mem;
  77.117  
  77.118      for ( bios_mem = (char *)ROMBIOS_BEGIN;
  77.119            bios_mem != (char *)ROMBIOS_END;
  77.120 -          bios_mem++ ) {
  77.121 -        if (strncmp(bios_mem, "___JMPT", 7) == 0)
  77.122 +          bios_mem++ )
  77.123 +        if ( !strncmp(bios_mem, "___JMPT", 7) )
  77.124              return bios_mem;
  77.125 -    }
  77.126  
  77.127      return NULL;
  77.128  }
  77.129  
  77.130 -/* copy relocated jumptable into the rombios */
  77.131 -static int copy_jumptable(unsigned char *elfarray)
  77.132 +/* Copy relocated jumptable into the rombios. */
  77.133 +static void copy_jumptable(char *elfarray)
  77.134  {
  77.135 -    int rc = 0;
  77.136      Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfarray;
  77.137      Elf32_Shdr *shdr = (Elf32_Shdr *)&elfarray[ehdr->e_shoff];
  77.138 -    Elf32_Shdr *shdr_strings = (Elf32_Shdr *)&shdr[ehdr->e_shstrndx];
  77.139 -    char *secstrings = (char *)&elfarray[shdr_strings->sh_offset];
  77.140 -    uint32_t *rombiosjumptable = (uint32_t *)get_jump_table_start();
  77.141 -    uint32_t *biosjumptable    = NULL;
  77.142 +    char *secstrings = &elfarray[shdr[ehdr->e_shstrndx].sh_offset];
  77.143 +    char *jump_table = get_jump_table_start();
  77.144      int i;
  77.145  
  77.146 -    if (rombiosjumptable == NULL) {
  77.147 -        return -3;
  77.148 +    /* Find the section with the jump table and copy to lower BIOS memory. */
  77.149 +    for ( i = 0; i < ehdr->e_shnum; i++ )
  77.150 +        if ( !strcmp(JUMPTABLE_SECTION_NAME, secstrings + shdr[i].sh_name) )
  77.151 +            break;
  77.152 +
  77.153 +    if ( i == ehdr->e_shnum )
  77.154 +    {
  77.155 +        printf("Could not find " JUMPTABLE_SECTION_NAME " section in file.\n");
  77.156 +        return;
  77.157      }
  77.158  
  77.159 -     /* find the section with the jump table  and copy to lower BIOS memory */
  77.160 -    for (i = 0; i < ehdr->e_shnum; i++) {
  77.161 -        if (!strcmp(JUMPTABLE_SECTION_NAME, secstrings + shdr[i].sh_name)) {
  77.162 -            uint32_t biosjumptableentries;
  77.163 -            biosjumptable        = (uint32_t *)shdr[i].sh_addr;
  77.164 -            biosjumptableentries = shdr[i].sh_size / 4;
  77.165 -            for (int j = 0; j < biosjumptableentries; j++) {
  77.166 -                rombiosjumptable[j] = biosjumptable[j];
  77.167 -                if (biosjumptable[j] == 0 &&
  77.168 -                    j < (biosjumptableentries - 1)) {
  77.169 -                    printf("WARNING: jumptable entry %d is NULL!\n",j);
  77.170 -                }
  77.171 -            }
  77.172 -            break;
  77.173 -        }
  77.174 +    if ( jump_table == NULL )
  77.175 +    {
  77.176 +        printf("Could not find jump table in file.\n");
  77.177 +        return;
  77.178      }
  77.179  
  77.180 -    if (biosjumptable == NULL) {
  77.181 -        printf("Could not find " JUMPTABLE_SECTION_NAME " section in file.\n");
  77.182 -        rc = -4;
  77.183 -    }
  77.184 -
  77.185 -    return 0;
  77.186 +    memcpy(jump_table, (char *)shdr[i].sh_addr, shdr[i].sh_size);
  77.187  }
  77.188  
  77.189 -static int relocate_32bitbios(unsigned char *elfarray, uint32_t elfarraysize)
  77.190 +static void relocate_32bitbios(char *elfarray, uint32_t elfarraysize)
  77.191  {
  77.192 -    int rc = 0;
  77.193      uint32_t mask = (64 * 1024) - 1;
  77.194 -    uint32_t to_malloc = (elfarraysize + mask) & ~mask; /* round to 64kb */
  77.195 -    unsigned char *highbiosarea;
  77.196 +    char *highbiosarea;
  77.197  
  77.198 -    highbiosarea = (unsigned char *)(long)
  77.199 -                           e820_malloc((uint64_t)to_malloc,
  77.200 -                                       E820_RESERVED,
  77.201 -                                       (uint64_t)0xffffffff);
  77.202 -
  77.203 -    if (highbiosarea != 0) {
  77.204 -        memcpy(highbiosarea, elfarray, elfarraysize);
  77.205 -        rc = relocate_elf(highbiosarea);
  77.206 -        if (rc == 0) {
  77.207 -            rc = copy_jumptable(highbiosarea);
  77.208 -        }
  77.209 -    } else {
  77.210 -        rc = -5;
  77.211 +    highbiosarea = (char *)(long)
  77.212 +        e820_malloc((elfarraysize + mask) & ~mask, /* round to 64kb */
  77.213 +                    E820_RESERVED,
  77.214 +                    (uint64_t)0xffffffff);
  77.215 +    if ( highbiosarea == NULL )
  77.216 +    {
  77.217 +        printf("No available memory for BIOS high memory area\n");
  77.218 +        return;
  77.219      }
  77.220  
  77.221 -    return rc;
  77.222 +    memcpy(highbiosarea, elfarray, elfarraysize);
  77.223 +    relocate_elf(highbiosarea);
  77.224 +    copy_jumptable(highbiosarea);
  77.225  }
  77.226  
  77.227 -int highbios_setup(void)
  77.228 +void highbios_setup(void)
  77.229  {
  77.230 -    return relocate_32bitbios((unsigned char *)highbios_array,
  77.231 -                              sizeof(highbios_array));
  77.232 +    relocate_32bitbios((char *)highbios_array, sizeof(highbios_array));
  77.233  }
    78.1 --- a/tools/firmware/hvmloader/acpi/acpi2_0.h	Wed Mar 21 17:03:00 2007 -0500
    78.2 +++ b/tools/firmware/hvmloader/acpi/acpi2_0.h	Wed Mar 21 18:08:31 2007 -0500
    78.3 @@ -49,8 +49,8 @@ struct acpi_header {
    78.4      uint32_t length;
    78.5      uint8_t  revision;
    78.6      uint8_t  checksum;
    78.7 -    uint8_t  oem_id[6];
    78.8 -    uint8_t  oem_table_id[8];
    78.9 +    char     oem_id[6];
   78.10 +    char     oem_table_id[8];
   78.11      uint32_t oem_revision;
   78.12      uint32_t creator_id;
   78.13      uint32_t creator_revision;
   78.14 @@ -90,7 +90,7 @@ struct acpi_20_generic_address {
   78.15  struct acpi_10_rsdp {
   78.16      uint64_t signature;
   78.17      uint8_t  checksum;
   78.18 -    uint8_t  oem_id[6];
   78.19 +    char     oem_id[6];
   78.20      uint8_t  reserved;
   78.21      uint32_t rsdt_address;
   78.22  };
   78.23 @@ -101,7 +101,7 @@ struct acpi_10_rsdp {
   78.24  struct acpi_20_rsdp {
   78.25      uint64_t signature;
   78.26      uint8_t  checksum;
   78.27 -    uint8_t  oem_id[6];
   78.28 +    char     oem_id[6];
   78.29      uint8_t  revision;
   78.30      uint32_t rsdt_address;
   78.31      uint32_t length;
   78.32 @@ -143,6 +143,51 @@ struct acpi_20_tcpa {
   78.33  #define ACPI_2_0_TCPA_LAML_SIZE (64*1024)
   78.34  
   78.35  /*
   78.36 + * Fixed ACPI Description Table Structure (FADT) in ACPI 1.0.
   78.37 + */
   78.38 +struct acpi_10_fadt {
   78.39 +    struct acpi_header header;
   78.40 +    uint32_t firmware_ctrl;
   78.41 +    uint32_t dsdt;
   78.42 +    uint8_t  reserved0;
   78.43 +    uint8_t  preferred_pm_profile;
   78.44 +    uint16_t sci_int;
   78.45 +    uint32_t smi_cmd;
   78.46 +    uint8_t  acpi_enable;
   78.47 +    uint8_t  acpi_disable;
   78.48 +    uint8_t  s4bios_req;
   78.49 +    uint8_t  pstate_cnt;
   78.50 +    uint32_t pm1a_evt_blk;
   78.51 +    uint32_t pm1b_evt_blk;
   78.52 +    uint32_t pm1a_cnt_blk;
   78.53 +    uint32_t pm1b_cnt_blk;
   78.54 +    uint32_t pm2_cnt_blk;
   78.55 +    uint32_t pm_tmr_blk;
   78.56 +    uint32_t gpe0_blk;
   78.57 +    uint32_t gpe1_blk;
   78.58 +    uint8_t  pm1_evt_len;
   78.59 +    uint8_t  pm1_cnt_len;
   78.60 +    uint8_t  pm2_cnt_len;
   78.61 +    uint8_t  pm_tmr_len;
   78.62 +    uint8_t  gpe0_blk_len;
   78.63 +    uint8_t  gpe1_blk_len;
   78.64 +    uint8_t  gpe1_base;
   78.65 +    uint8_t  cst_cnt;
   78.66 +    uint16_t p_lvl2_lat;
   78.67 +    uint16_t p_lvl3_lat;
   78.68 +    uint16_t flush_size;
   78.69 +    uint16_t flush_stride;
   78.70 +    uint8_t  duty_offset;
   78.71 +    uint8_t  duty_width;
   78.72 +    uint8_t  day_alrm;
   78.73 +    uint8_t  mon_alrm;
   78.74 +    uint8_t  century;
   78.75 +    uint16_t iapc_boot_arch;
   78.76 +    uint8_t  reserved1;
   78.77 +    uint32_t flags;
   78.78 +};
   78.79 +
   78.80 +/*
   78.81   * Fixed ACPI Description Table Structure (FADT).
   78.82   */
   78.83  struct acpi_20_fadt {
   78.84 @@ -345,6 +390,7 @@ struct acpi_20_madt_intsrcovr {
   78.85  #define ACPI_2_0_XSDT_REVISION 0x01
   78.86  #define ACPI_2_0_TCPA_REVISION 0x02
   78.87  #define ACPI_2_0_HPET_REVISION 0x01
   78.88 +#define ACPI_1_0_FADT_REVISION 0x01
   78.89  
   78.90  #pragma pack ()
   78.91  
    79.1 --- a/tools/firmware/hvmloader/acpi/build.c	Wed Mar 21 17:03:00 2007 -0500
    79.2 +++ b/tools/firmware/hvmloader/acpi/build.c	Wed Mar 21 18:08:31 2007 -0500
    79.3 @@ -20,9 +20,9 @@
    79.4  #include "ssdt_tpm.h"
    79.5  #include "../config.h"
    79.6  #include "../util.h"
    79.7 -#include <xen/hvm/e820.h>
    79.8  
    79.9 -#define align16(sz) (((sz) + 15) & ~15)
   79.10 +#define align16(sz)        (((sz) + 15) & ~15)
   79.11 +#define fixed_strcpy(d, s) strncpy((d), (s), sizeof(d))
   79.12  
   79.13  extern struct acpi_20_rsdp Rsdp;
   79.14  extern struct acpi_20_rsdt Rsdt;
   79.15 @@ -57,8 +57,8 @@ int construct_madt(struct acpi_20_madt *
   79.16      memset(madt, 0, sizeof(*madt));
   79.17      madt->header.signature    = ACPI_2_0_MADT_SIGNATURE;
   79.18      madt->header.revision     = ACPI_2_0_MADT_REVISION;
   79.19 -    strncpy(madt->header.oem_id, ACPI_OEM_ID, 6);
   79.20 -    strncpy(madt->header.oem_table_id, ACPI_OEM_TABLE_ID, 8);
   79.21 +    fixed_strcpy(madt->header.oem_id, ACPI_OEM_ID);
   79.22 +    fixed_strcpy(madt->header.oem_table_id, ACPI_OEM_TABLE_ID);
   79.23      madt->header.oem_revision = ACPI_OEM_REVISION;
   79.24      madt->header.creator_id   = ACPI_CREATOR_ID;
   79.25      madt->header.creator_revision = ACPI_CREATOR_REVISION;
   79.26 @@ -131,8 +131,8 @@ int construct_hpet(struct acpi_20_hpet *
   79.27      memset(hpet, 0, sizeof(*hpet));
   79.28      hpet->header.signature    = ACPI_2_0_HPET_SIGNATURE;
   79.29      hpet->header.revision     = ACPI_2_0_HPET_REVISION;
   79.30 -    strncpy(hpet->header.oem_id, ACPI_OEM_ID, 6);
   79.31 -    strncpy(hpet->header.oem_table_id, ACPI_OEM_TABLE_ID, 8);
   79.32 +    fixed_strcpy(hpet->header.oem_id, ACPI_OEM_ID);
   79.33 +    fixed_strcpy(hpet->header.oem_table_id, ACPI_OEM_TABLE_ID);
   79.34      hpet->header.oem_revision = ACPI_OEM_REVISION;
   79.35      hpet->header.creator_id   = ACPI_CREATOR_ID;
   79.36      hpet->header.creator_revision = ACPI_CREATOR_REVISION;
   79.37 @@ -150,6 +150,7 @@ int construct_processor_objects(uint8_t 
   79.38  {
   79.39      static const char pdat[13] = { 0x5b, 0x83, 0x0b, 0x50, 0x52 };
   79.40      static const char hex[] = "0123456789ABCDEF";
   79.41 +    static const char pr_scope[] = "\\_PR_";
   79.42      unsigned int i, length, nr_cpus = get_vcpu_nr();
   79.43      struct acpi_header *hdr;
   79.44      uint8_t *p = buf;
   79.45 @@ -161,8 +162,8 @@ int construct_processor_objects(uint8_t 
   79.46      hdr = (struct acpi_header *)p;
   79.47      hdr->signature = ASCII32('S','S','D','T');
   79.48      hdr->revision  = 2;
   79.49 -    strncpy(hdr->oem_id, ACPI_OEM_ID, 6);
   79.50 -    strncpy(hdr->oem_table_id, ACPI_OEM_TABLE_ID, 8);
   79.51 +    fixed_strcpy(hdr->oem_id, ACPI_OEM_ID);
   79.52 +    fixed_strcpy(hdr->oem_table_id, ACPI_OEM_TABLE_ID);
   79.53      hdr->oem_revision = ACPI_OEM_REVISION;
   79.54      hdr->creator_id = ACPI_CREATOR_ID;
   79.55      hdr->creator_revision = ACPI_CREATOR_REVISION;
   79.56 @@ -176,7 +177,7 @@ int construct_processor_objects(uint8_t 
   79.57      *p++ = 0x10;
   79.58  
   79.59      /* PkgLength (includes length bytes!). */
   79.60 -    length = 1 + 5 + (nr_cpus * sizeof(pdat));
   79.61 +    length = 1 + strlen(pr_scope) + (nr_cpus * sizeof(pdat));
   79.62      if ( length <= 0x3f )
   79.63      {
   79.64          *p++ = length;
   79.65 @@ -195,8 +196,8 @@ int construct_processor_objects(uint8_t 
   79.66      }
   79.67  
   79.68      /* NameString */
   79.69 -    strncpy(p, "\\_PR_", 5);
   79.70 -    p += 5;
   79.71 +    strncpy(p, pr_scope, strlen(pr_scope));
   79.72 +    p += strlen(pr_scope);
   79.73  
   79.74      /*
   79.75       * 3. Processor Objects.
   79.76 @@ -263,8 +264,8 @@ int construct_secondary_tables(uint8_t *
   79.77          tcpa->header.signature = ACPI_2_0_TCPA_SIGNATURE;
   79.78          tcpa->header.length    = sizeof(*tcpa);
   79.79          tcpa->header.revision  = ACPI_2_0_TCPA_REVISION;
   79.80 -        strncpy(tcpa->header.oem_id, ACPI_OEM_ID, 6);
   79.81 -        strncpy(tcpa->header.oem_table_id, ACPI_OEM_TABLE_ID, 8);
   79.82 +        fixed_strcpy(tcpa->header.oem_id, ACPI_OEM_ID);
   79.83 +        fixed_strcpy(tcpa->header.oem_table_id, ACPI_OEM_TABLE_ID);
   79.84          tcpa->header.oem_revision = ACPI_OEM_REVISION;
   79.85          tcpa->header.creator_id   = ACPI_CREATOR_ID;
   79.86          tcpa->header.creator_revision = ACPI_CREATOR_REVISION;
   79.87 @@ -291,6 +292,7 @@ int acpi_build_tables(uint8_t *buf)
   79.88      struct acpi_20_rsdt *rsdt;
   79.89      struct acpi_20_xsdt *xsdt;
   79.90      struct acpi_20_fadt *fadt;
   79.91 +    struct acpi_10_fadt *fadt_10;
   79.92      struct acpi_20_facs *facs;
   79.93      unsigned char       *dsdt;
   79.94      unsigned long        secondary_tables[16];
   79.95 @@ -304,6 +306,25 @@ int acpi_build_tables(uint8_t *buf)
   79.96      memcpy(dsdt, &AmlCode, DsdtLen);
   79.97      offset += align16(DsdtLen);
   79.98  
   79.99 +    /*
  79.100 +     * N.B. ACPI 1.0 operating systems may not handle FADT with revision 2
  79.101 +     * or above properly, notably Windows 2000, which tries to copy FADT
  79.102 +     * into a 116 bytes buffer thus causing an overflow. The solution is to
  79.103 +     * link the higher revision FADT with the XSDT only and introduce a
  79.104 +     * compatible revision 1 FADT that is linked with the RSDT. Refer to:
  79.105 +     *     http://www.acpi.info/presentations/S01USMOBS169_OS%20new.ppt
  79.106 +     */
  79.107 +    fadt_10 = (struct acpi_10_fadt *)&buf[offset];
  79.108 +    memcpy(fadt_10, &Fadt, sizeof(struct acpi_10_fadt));
  79.109 +    offset += align16(sizeof(struct acpi_10_fadt));
  79.110 +    fadt_10->header.length = sizeof(struct acpi_10_fadt);
  79.111 +    fadt_10->header.revision = ACPI_1_0_FADT_REVISION;
  79.112 +    fadt_10->dsdt          = (unsigned long)dsdt;
  79.113 +    fadt_10->firmware_ctrl = (unsigned long)facs;
  79.114 +    set_checksum(fadt_10,
  79.115 +                 offsetof(struct acpi_header, checksum),
  79.116 +                 sizeof(struct acpi_10_fadt));
  79.117 +
  79.118      fadt = (struct acpi_20_fadt *)&buf[offset];
  79.119      memcpy(fadt, &Fadt, sizeof(struct acpi_20_fadt));
  79.120      offset += align16(sizeof(struct acpi_20_fadt));
  79.121 @@ -330,7 +351,7 @@ int acpi_build_tables(uint8_t *buf)
  79.122  
  79.123      rsdt = (struct acpi_20_rsdt *)&buf[offset];
  79.124      memcpy(rsdt, &Rsdt, sizeof(struct acpi_header));
  79.125 -    rsdt->entry[0] = (unsigned long)fadt;
  79.126 +    rsdt->entry[0] = (unsigned long)fadt_10;
  79.127      for ( i = 0; secondary_tables[i]; i++ )
  79.128          rsdt->entry[i+1] = secondary_tables[i];
  79.129      rsdt->header.length = sizeof(struct acpi_header) + (i+1)*sizeof(uint32_t);
    80.1 --- a/tools/firmware/hvmloader/hvmloader.c	Wed Mar 21 17:03:00 2007 -0500
    80.2 +++ b/tools/firmware/hvmloader/hvmloader.c	Wed Mar 21 18:08:31 2007 -0500
    80.3 @@ -29,7 +29,6 @@
    80.4  #include "pci_regs.h"
    80.5  #include <xen/version.h>
    80.6  #include <xen/hvm/params.h>
    80.7 -#include <xen/hvm/e820.h>
    80.8  
    80.9  /* memory map */
   80.10  #define HYPERCALL_PHYSICAL_ADDRESS    0x00080000
   80.11 @@ -38,23 +37,53 @@
   80.12  #define VMXASSIST_PHYSICAL_ADDRESS    0x000D0000
   80.13  #define ROMBIOS_PHYSICAL_ADDRESS      0x000F0000
   80.14  
   80.15 -/* invoke SVM's paged realmode support */
   80.16 -#define SVM_VMMCALL_RESET_TO_REALMODE 0x80000001
   80.17 -
   80.18 -/*
   80.19 - * C runtime start off
   80.20 - */
   80.21  asm(
   80.22      "    .text                       \n"
   80.23      "    .globl _start               \n"
   80.24      "_start:                         \n"
   80.25 +    /* C runtime kickoff. */
   80.26      "    cld                         \n"
   80.27      "    cli                         \n"
   80.28 +    "    movl $stack_top,%esp        \n"
   80.29 +    "    movl %esp,%ebp              \n"
   80.30 +    "    call main                   \n"
   80.31 +    /* Relocate real-mode trampoline to 0x0. */
   80.32 +    "    mov  $trampoline_start,%esi \n"
   80.33 +    "    xor  %edi,%edi              \n"
   80.34 +    "    mov  $trampoline_end,%ecx   \n"
   80.35 +    "    sub  %esi,%ecx              \n"
   80.36 +    "    rep  movsb                  \n"
   80.37 +    /* Load real-mode compatible segment state (base 0x0000, limit 0xffff). */
   80.38      "    lgdt gdt_desr               \n"
   80.39 -    "    movl $stack_top, %esp       \n"
   80.40 -    "    movl %esp, %ebp             \n"
   80.41 -    "    call main                   \n"
   80.42 -    "    ud2                         \n"
   80.43 +    "    mov  $0x0010,%ax            \n"
   80.44 +    "    mov  %ax,%ds                \n"
   80.45 +    "    mov  %ax,%es                \n"
   80.46 +    "    mov  %ax,%fs                \n"
   80.47 +    "    mov  %ax,%gs                \n"
   80.48 +    "    mov  %ax,%ss                \n"
   80.49 +    /* Initialise all 32-bit GPRs to zero. */
   80.50 +    "    xor  %eax,%eax              \n"
   80.51 +    "    xor  %ebx,%ebx              \n"
   80.52 +    "    xor  %ecx,%ecx              \n"
   80.53 +    "    xor  %edx,%edx              \n"
   80.54 +    "    xor  %esp,%esp              \n"
   80.55 +    "    xor  %ebp,%ebp              \n"
   80.56 +    "    xor  %esi,%esi              \n"
   80.57 +    "    xor  %edi,%edi              \n"
   80.58 +    /* Enter real mode, reload all segment registers and IDT. */
   80.59 +    "    ljmp $0x8,$0x0              \n"
   80.60 +    "trampoline_start: .code16       \n"
   80.61 +    "    mov  %eax,%cr0              \n"
   80.62 +    "    ljmp $0,$1f-trampoline_start\n"
   80.63 +    "1:  mov  %ax,%ds                \n"
   80.64 +    "    mov  %ax,%es                \n"
   80.65 +    "    mov  %ax,%fs                \n"
   80.66 +    "    mov  %ax,%gs                \n"
   80.67 +    "    mov  %ax,%ss                \n"
   80.68 +    "    lidt 1f-trampoline_start    \n"
   80.69 +    "    ljmp $0xf000,$0xfff0        \n"
   80.70 +    "1:  .word 0x3ff,0,0             \n"
   80.71 +    "trampoline_end:   .code32       \n"
   80.72      "                                \n"
   80.73      "gdt_desr:                       \n"
   80.74      "    .word gdt_end - gdt - 1     \n"
   80.75 @@ -63,8 +92,8 @@ asm(
   80.76      "    .align 8                    \n"
   80.77      "gdt:                            \n"
   80.78      "    .quad 0x0000000000000000    \n"
   80.79 -    "    .quad 0x00CF92000000FFFF    \n"
   80.80 -    "    .quad 0x00CF9A000000FFFF    \n"
   80.81 +    "    .quad 0x00009a000000ffff    \n" /* Ring 0 code, base 0 limit 0xffff */
   80.82 +    "    .quad 0x000092000000ffff    \n" /* Ring 0 data, base 0 limit 0xffff */
   80.83      "gdt_end:                        \n"
   80.84      "                                \n"
   80.85      "    .bss                        \n"
   80.86 @@ -84,19 +113,6 @@ cirrus_check(void)
   80.87  }
   80.88  
   80.89  static int
   80.90 -vmmcall(int function, int edi, int esi, int edx, int ecx, int ebx)
   80.91 -{
   80.92 -    int eax;
   80.93 -
   80.94 -    __asm__ __volatile__ (
   80.95 -        ".byte 0x0F,0x01,0xD9"
   80.96 -        : "=a" (eax)
   80.97 -        : "a"(function),
   80.98 -        "b"(ebx), "c"(ecx), "d"(edx), "D"(edi), "S"(esi) );
   80.99 -    return eax;
  80.100 -}
  80.101 -
  80.102 -static int
  80.103  check_amd(void)
  80.104  {
  80.105      char id[12];
  80.106 @@ -280,25 +296,57 @@ static void pci_setup(void)
  80.107      }
  80.108  }
  80.109  
  80.110 -static 
  80.111 -int must_load_nic(void) 
  80.112 +/*
  80.113 + * If the network card is in the boot order, load the Etherboot option ROM.
  80.114 + * Read the boot order bytes from CMOS and check if any of them are 0x4.
  80.115 + */
  80.116 +static int must_load_nic(void) 
  80.117  {
  80.118 -    /* If the network card is in the boot order, load the Etherboot 
  80.119 -     * option ROM.  Read the boot order bytes from CMOS and check 
  80.120 -     * if any of them are 0x4. */
  80.121      uint8_t boot_order;
  80.122  
  80.123 -    /* Read CMOS register 0x3d (boot choices 0 and 1) */
  80.124 -    outb(0x70, 0x3d);
  80.125 -    boot_order = inb(0x71);
  80.126 -    if ( (boot_order & 0xf) == 0x4 || (boot_order & 0xf0) == 0x40 ) 
  80.127 +    /* Read CMOS register 0x3d (boot choices 0 and 1). */
  80.128 +    boot_order = cmos_inb(0x3d);
  80.129 +    if ( ((boot_order & 0xf) == 0x4) || ((boot_order & 0xf0) == 0x40) ) 
  80.130          return 1;
  80.131 -    /* Read CMOS register 0x38 (boot choice 2 and FDD test flag) */
  80.132 -    outb(0x70, 0x38);
  80.133 -    boot_order = inb(0x71);
  80.134 -    if ( (boot_order & 0xf0) == 0x40 ) 
  80.135 -        return 1;
  80.136 -    return 0;
  80.137 +
  80.138 +    /* Read CMOS register 0x38 (boot choice 2 and FDD test flag). */
  80.139 +    boot_order = cmos_inb(0x38);
  80.140 +    return ((boot_order & 0xf0) == 0x40);
  80.141 +}
  80.142 +
  80.143 +/* Replace possibly erroneous memory-size CMOS fields with correct values. */
  80.144 +static void cmos_write_memory_size(void)
  80.145 +{
  80.146 +    struct e820entry *map = E820_MAP;
  80.147 +    int i, nr = *E820_MAP_NR;
  80.148 +    uint32_t base_mem = 640, ext_mem = 0, alt_mem = 0;
  80.149 +
  80.150 +    for ( i = 0; i < nr; i++ )
  80.151 +        if ( (map[i].addr >= 0x100000) && (map[i].type == E820_RAM) )
  80.152 +            break;
  80.153 +
  80.154 +    if ( i != nr )
  80.155 +    {
  80.156 +        alt_mem = ext_mem = map[i].addr + map[i].size;
  80.157 +        ext_mem = (ext_mem > 0x0100000) ? (ext_mem - 0x0100000) >> 10 : 0;
  80.158 +        if ( ext_mem > 0xffff )
  80.159 +            ext_mem = 0xffff;
  80.160 +        alt_mem = (alt_mem > 0x1000000) ? (alt_mem - 0x1000000) >> 16 : 0;
  80.161 +    }
  80.162 +
  80.163 +    /* All BIOSes: conventional memory (640kB). */
  80.164 +    cmos_outb(0x15, (uint8_t)(base_mem >> 0));
  80.165 +    cmos_outb(0x16, (uint8_t)(base_mem >> 8));
  80.166 +
  80.167 +    /* All BIOSes: extended memory (1kB chunks above 1MB). */
  80.168 +    cmos_outb(0x17, (uint8_t)( ext_mem >> 0));
  80.169 +    cmos_outb(0x18, (uint8_t)( ext_mem >> 8));
  80.170 +    cmos_outb(0x30, (uint8_t)( ext_mem >> 0));
  80.171 +    cmos_outb(0x31, (uint8_t)( ext_mem >> 8));
  80.172 +
  80.173 +    /* Some BIOSes: alternative extended memory (64kB chunks above 16MB). */
  80.174 +    cmos_outb(0x34, (uint8_t)( alt_mem >> 0));
  80.175 +    cmos_outb(0x35, (uint8_t)( alt_mem >> 8));
  80.176  }
  80.177  
  80.178  int main(void)
  80.179 @@ -349,13 +397,9 @@ int main(void)
  80.180          ASSERT((ACPI_PHYSICAL_ADDRESS + acpi_sz) <= 0xF0000);
  80.181      }
  80.182  
  80.183 -    if ( check_amd() )
  80.184 -    {
  80.185 -        /* AMD implies this is SVM */
  80.186 -        printf("SVM go ...\n");
  80.187 -        vmmcall(SVM_VMMCALL_RESET_TO_REALMODE, 0, 0, 0, 0, 0);
  80.188 -    }
  80.189 -    else
  80.190 +    cmos_write_memory_size();
  80.191 +
  80.192 +    if ( !check_amd() )
  80.193      {
  80.194          printf("Loading VMXAssist ...\n");
  80.195          memcpy((void *)VMXASSIST_PHYSICAL_ADDRESS,
  80.196 @@ -368,7 +412,7 @@ int main(void)
  80.197              );
  80.198      }
  80.199  
  80.200 -    printf("Failed to invoke ROMBIOS\n");
  80.201 +    printf("Invoking ROMBIOS ...\n");
  80.202      return 0;
  80.203  }
  80.204  
    81.1 --- a/tools/firmware/hvmloader/smbios.c	Wed Mar 21 17:03:00 2007 -0500
    81.2 +++ b/tools/firmware/hvmloader/smbios.c	Wed Mar 21 18:08:31 2007 -0500
    81.3 @@ -22,7 +22,6 @@
    81.4  
    81.5  #include <stdint.h>
    81.6  #include <xen/version.h>
    81.7 -#include <xen/hvm/e820.h>
    81.8  #include "smbios.h"
    81.9  #include "smbios_types.h"
   81.10  #include "util.h"
   81.11 @@ -129,47 +128,32 @@ write_smbios_tables(void *start,
   81.12      return (size_t)((char *)p - (char *)start);
   81.13  }
   81.14  
   81.15 -/* This tries to figure out how much pseudo-physical memory (in MB)
   81.16 -   is allocated to the current domU.
   81.17 -
   81.18 -   It iterates through the e820 table, adding up the 'usable' and
   81.19 -   'reserved' entries and rounding up to the nearest MB.
   81.20 -
   81.21 -   The e820map is not at e820 in hvmloader, so this uses the
   81.22 -   E820_MAP_* constants from e820.h to pick it up where libxenguest
   81.23 -   left it.
   81.24 - */
   81.25 +/* Calculate how much pseudo-physical memory (in MB) is allocated to us. */
   81.26  static uint64_t
   81.27  get_memsize(void)
   81.28  {
   81.29 -    struct e820entry *map = NULL;
   81.30 -    uint8_t num_entries = 0;
   81.31 +    struct e820entry *map = E820_MAP;
   81.32 +    uint8_t num_entries = *E820_MAP_NR;
   81.33      uint64_t memsize = 0;
   81.34 -    uint8_t i;
   81.35 +    int i;
   81.36  
   81.37 -    map = (struct e820entry *) (E820_MAP_PAGE + E820_MAP_OFFSET);
   81.38 -    num_entries = *((uint8_t *) (E820_MAP_PAGE + E820_MAP_NR_OFFSET));
   81.39 -
   81.40 -    /* walk through e820map, ignoring any entries that aren't marked
   81.41 -       as usable or reserved. */
   81.42 -
   81.43 +    /*
   81.44 +     * Walk through e820map, ignoring any entries that aren't marked
   81.45 +     * as usable or reserved.
   81.46 +     */
   81.47      for ( i = 0; i < num_entries; i++ )
   81.48      {
   81.49 -        if (map->type == E820_RAM || map->type == E820_RESERVED)
   81.50 +        if ( (map->type == E820_RAM) || (map->type == E820_RESERVED) )
   81.51              memsize += map->size;
   81.52          map++;
   81.53      }
   81.54  
   81.55 -    /* Round up to the nearest MB.  The user specifies domU
   81.56 -       pseudo-physical memory in megabytes, so not doing this
   81.57 -       could easily lead to reporting one less MB than the user
   81.58 -       specified. */
   81.59 -    if ( memsize & ((1<<20)-1) )
   81.60 -        memsize = (memsize >> 20) + 1;
   81.61 -    else
   81.62 -        memsize = (memsize >> 20);
   81.63 -
   81.64 -    return memsize;
   81.65 +    /*
   81.66 +     * Round up to the nearest MB.  The user specifies domU pseudo-physical 
   81.67 +     * memory in megabytes, so not doing this could easily lead to reporting 
   81.68 +     * one less MB than the user specified.
   81.69 +     */
   81.70 +    return (memsize + (1 << 20) - 1) >> 20;
   81.71  }
   81.72  
   81.73  void
    82.1 --- a/tools/firmware/hvmloader/util.c	Wed Mar 21 17:03:00 2007 -0500
    82.2 +++ b/tools/firmware/hvmloader/util.c	Wed Mar 21 18:08:31 2007 -0500
    82.3 @@ -27,17 +27,17 @@
    82.4  
    82.5  void outb(uint16_t addr, uint8_t val)
    82.6  {
    82.7 -    __asm__ __volatile__ ( "outb %%al, %%dx" :: "d"(addr), "a"(val) );
    82.8 +    __asm__ __volatile__ ( "outb %%al, %%dx" : : "d" (addr), "a" (val) );
    82.9  }
   82.10  
   82.11  void outw(uint16_t addr, uint16_t val)
   82.12  {
   82.13 -    __asm__ __volatile__ ( "outw %%ax, %%dx" :: "d"(addr), "a"(val) );
   82.14 +    __asm__ __volatile__ ( "outw %%ax, %%dx" : : "d" (addr), "a" (val) );
   82.15  }
   82.16  
   82.17  void outl(uint16_t addr, uint32_t val)
   82.18  {
   82.19 -    __asm__ __volatile__ ( "outl %%eax, %%dx" :: "d"(addr), "a"(val) );
   82.20 +    __asm__ __volatile__ ( "outl %%eax, %%dx" : : "d" (addr), "a" (val) );
   82.21  }
   82.22  
   82.23  uint8_t inb(uint16_t addr)
   82.24 @@ -61,6 +61,18 @@ uint32_t inl(uint16_t addr)
   82.25      return val;
   82.26  }
   82.27  
   82.28 +uint8_t cmos_inb(uint8_t idx)
   82.29 +{
   82.30 +    outb(0x70, idx);
   82.31 +    return inb(0x71);
   82.32 +}
   82.33 +
   82.34 +void cmos_outb(uint8_t idx, uint8_t val)
   82.35 +{
   82.36 +    outb(0x70, idx);
   82.37 +    outb(0x71, val);
   82.38 +}
   82.39 +
   82.40  char *itoa(char *a, unsigned int i)
   82.41  {
   82.42      unsigned int _i = i, x = 0;
   82.43 @@ -280,9 +292,6 @@ uuid_to_string(char *dest, uint8_t *uuid
   82.44      *p = '\0';
   82.45  }
   82.46  
   82.47 -#include <xen/hvm/e820.h>
   82.48 -#define E820_MAP_NR ((unsigned char *)E820_MAP_PAGE + E820_MAP_NR_OFFSET)
   82.49 -#define E820_MAP    ((struct e820entry *)(E820_MAP_PAGE + E820_MAP_OFFSET))
   82.50  uint64_t e820_malloc(uint64_t size, uint32_t type, uint64_t mask)
   82.51  {
   82.52      uint64_t addr = 0;
    83.1 --- a/tools/firmware/hvmloader/util.h	Wed Mar 21 17:03:00 2007 -0500
    83.2 +++ b/tools/firmware/hvmloader/util.h	Wed Mar 21 18:08:31 2007 -0500
    83.3 @@ -26,6 +26,10 @@ uint8_t  inb(uint16_t addr);
    83.4  uint16_t inw(uint16_t addr);
    83.5  uint32_t inl(uint16_t addr);
    83.6  
    83.7 +/* CMOS access */
    83.8 +uint8_t cmos_inb(uint8_t idx);
    83.9 +void cmos_outb(uint8_t idx, uint8_t val);
   83.10 +
   83.11  /* APIC access */
   83.12  uint32_t ioapic_read(uint32_t reg);
   83.13  void ioapic_write(uint32_t reg, uint32_t val);
   83.14 @@ -78,9 +82,13 @@ int vprintf(const char *fmt, va_list ap)
   83.15  /* Allocate region of specified type in the e820 table. */
   83.16  uint64_t e820_malloc(uint64_t size, uint32_t type, uint64_t mask);
   83.17  
   83.18 +/* General e820 access. */
   83.19 +#include <xen/hvm/e820.h>
   83.20 +#define E820_MAP_NR ((unsigned char *)E820_MAP_PAGE + E820_MAP_NR_OFFSET)
   83.21 +#define E820_MAP    ((struct e820entry *)(E820_MAP_PAGE + E820_MAP_OFFSET))
   83.22 +
   83.23  /* Prepare the 32bit BIOS */
   83.24 -int highbios_setup(void);
   83.25 -
   83.26 +void highbios_setup(void);
   83.27  
   83.28  #define isdigit(c) ((c) >= '0' && (c) <= '9')
   83.29  
    84.1 --- a/tools/firmware/rombios/32bit/tcgbios/tcgbios.c	Wed Mar 21 17:03:00 2007 -0500
    84.2 +++ b/tools/firmware/rombios/32bit/tcgbios/tcgbios.c	Wed Mar 21 18:08:31 2007 -0500
    84.3 @@ -95,13 +95,15 @@ struct ptti_cust *TCG_CommandList[] = {
    84.4  };
    84.5  
    84.6  /* local function prototypes */
    84.7 -static void sha1(const unsigned char *data, uint32_t length, unsigned char *hash);
    84.8 +static void sha1(const unsigned char *data, uint32_t length,
    84.9 +                 unsigned char *hash);
   84.10  static uint32_t TCG_ShutdownPreBootInterface(uint32_t ebx);
   84.11  static uint32_t HashAll32(struct hai *hai, unsigned char *hash,
   84.12                            uint32_t magic, uint32_t ecx, uint32_t edx);
   84.13  static uint32_t HashLogExtendEvent32(struct hleei_short *hleei_s,
   84.14                                       struct hleeo *hleeo,
   84.15 -                                     uint32_t magic, uint32_t ecx, uint32_t edx);
   84.16 +                                     uint32_t magic, uint32_t ecx,
   84.17 +                                     uint32_t edx);
   84.18  static uint32_t HashLogEvent32(struct hlei *hlei, struct hleo *hleo,
   84.19                                 uint32_t ebx, uint32_t ecx, uint32_t edx);
   84.20  static uint32_t PassThroughToTPM32(struct pttti *pttti, struct pttto *pttto,
   84.21 @@ -181,8 +183,7 @@ uint32_t MA_InitTPM(uint16_t startupcode
   84.22  }
   84.23  
   84.24  static
   84.25 -uint32_t MA_Transmit(unsigned char *cmdbuffer,
   84.26 -                     unsigned char *respbuffer,
   84.27 +uint32_t MA_Transmit(unsigned char *cmdbuffer, unsigned char *respbuffer,
   84.28                       uint32_t respbufferlen)
   84.29  {
   84.30  	uint32_t rc = 0;
   84.31 @@ -289,15 +290,14 @@ void tcpa_acpi_init(void)
   84.32  		uint32_t ctr = 0;
   84.33  		/* get RSDT from RSDP */
   84.34  		rsdt   = (struct acpi_20_rsdt *)rsdp->rsdt_address;
   84.35 -		/* rsdt may be anywhere in 32bit space */
   84.36  		length = rsdt->header.length;
   84.37  		off = 36;
   84.38  		while ((off + 3) < length) {
   84.39  			/* try all pointers to structures */
   84.40  			tcpa = (struct acpi_20_tcpa *)rsdt->entry[ctr];
   84.41  			/* valid TCPA ACPI table ? */
   84.42 -			if (ACPI_2_0_TCPA_SIGNATURE == tcpa->header.signature &&
   84.43 -			    acpi_validate_entry(&tcpa->header) == 0) {
   84.44 +			if (ACPI_2_0_TCPA_SIGNATURE == tcpa->header.signature
   84.45 +			    && acpi_validate_entry(&tcpa->header) == 0) {
   84.46  				found = 1;
   84.47  				break;
   84.48  			}
   84.49 @@ -311,7 +311,6 @@ void tcpa_acpi_init(void)
   84.50  		tcpa = 0;
   84.51  	}
   84.52  
   84.53 -	/* initialize the TCPA part of the EBDA with our data */
   84.54  	tcpa_acpi.tcpa_ptr = tcpa;
   84.55  	tcpa_acpi.lasa_last_ptr = 0;
   84.56  	tcpa_acpi.entry_count = 0;
   84.57 @@ -748,9 +747,7 @@ void tcpa_measure_post(Bit32u from, Bit3
   84.58  }
   84.59  
   84.60  static
   84.61 -uint32_t SendCommand32(uint32_t idx,
   84.62 -                     struct pttto *pttto,
   84.63 -                     uint32_t size_ptto)
   84.64 +uint32_t SendCommand32(uint32_t idx, struct pttto *pttto, uint32_t size_ptto)
   84.65  {
   84.66  	uint32_t rc = 0;
   84.67  	struct pttti *pttti = (struct pttti *)TCG_CommandList[idx];
   84.68 @@ -796,7 +793,8 @@ uint32_t tcpa_initialize_tpm(uint32_t ph
   84.69  	uint32_t pttto_size = sizeof(_pttto);
   84.70  
   84.71  	if (rc == 0) {
   84.72 -		rc = SendCommand32(IDX_CMD_TPM_Startup_0x01, pttto, pttto_size);
   84.73 +		rc = SendCommand32(IDX_CMD_TPM_Startup_0x01, pttto,
   84.74 +		                   pttto_size);
   84.75  	}
   84.76  
   84.77  	if (rc == 0 && physpres != 0) {
   84.78 @@ -884,11 +882,8 @@ uint32_t _TCG_TPM_Extend(unsigned char *
   84.79  
   84.80  
   84.81  static
   84.82 -uint32_t HashLogExtendEvent32(struct hleei_short *hleei_s,
   84.83 -                            struct hleeo *hleeo,
   84.84 -                            uint32_t magic,
   84.85 -                            uint32_t ecx,
   84.86 -                            uint32_t edx)
   84.87 +uint32_t HashLogExtendEvent32(struct hleei_short *hleei_s, struct hleeo *hleeo,
   84.88 +                              uint32_t magic, uint32_t ecx, uint32_t edx)
   84.89  {
   84.90  	uint32_t rc = 0;
   84.91  	uint16_t size;
   84.92 @@ -978,11 +973,8 @@ uint32_t HashLogExtendEvent32(struct hle
   84.93  
   84.94  
   84.95  static
   84.96 -uint32_t PassThroughToTPM32(struct pttti *pttti,
   84.97 -                          struct pttto *pttto,
   84.98 -                          uint32_t magic,
   84.99 -                          uint32_t ecx,
  84.100 -                          uint32_t edx)
  84.101 +uint32_t PassThroughToTPM32(struct pttti *pttti, struct pttto *pttto,
  84.102 +                            uint32_t magic, uint32_t ecx, uint32_t edx)
  84.103  {
  84.104  	uint32_t rc = 0;
  84.105  	uint8_t *cmd32;
  84.106 @@ -1047,9 +1039,7 @@ uint32_t TCG_ShutdownPreBootInterface(ui
  84.107  
  84.108  static
  84.109  uint32_t HashLogEvent32(struct hlei *hlei, struct hleo *hleo,
  84.110 -                      uint32_t ebx,
  84.111 -                      uint32_t ecx,
  84.112 -                      uint32_t edx)
  84.113 +                        uint32_t ebx, uint32_t ecx, uint32_t edx)
  84.114  {
  84.115  	uint32_t rc = 0;
  84.116  	uint16_t size;
  84.117 @@ -1144,9 +1134,7 @@ uint32_t HashLogEvent32(struct hlei *hle
  84.118  
  84.119  static
  84.120  uint32_t HashAll32(struct hai *hai, unsigned char *hash,
  84.121 -                 uint32_t magic,
  84.122 -                 uint32_t ecx,
  84.123 -                 uint32_t edx)
  84.124 +                   uint32_t magic, uint32_t ecx, uint32_t edx)
  84.125  {
  84.126  	uint32_t rc = 0;
  84.127  
  84.128 @@ -1187,9 +1175,7 @@ uint32_t HashAll32(struct hai *hai, unsi
  84.129  
  84.130  static
  84.131  uint32_t TSS32(struct ti *ti, struct to *to,
  84.132 -             uint32_t ebx,
  84.133 -             uint32_t ecx,
  84.134 -             uint32_t edx)
  84.135 +               uint32_t ebx, uint32_t ecx, uint32_t edx)
  84.136  {
  84.137  	uint32_t rc = 0;
  84.138  	if (TCG_IsShutdownPreBootInterface() == 0) {
  84.139 @@ -1209,11 +1195,11 @@ uint32_t TSS32(struct ti *ti, struct to 
  84.140  
  84.141  static
  84.142  uint32_t CompactHashLogExtendEvent32(unsigned char *buffer,
  84.143 -                                   uint32_t info,
  84.144 -                                   uint32_t magic,
  84.145 -                                   uint32_t length,
  84.146 -                                   uint32_t pcrindex,
  84.147 -                                   uint32_t *edx_ptr)
  84.148 +                                     uint32_t info,
  84.149 +                                     uint32_t magic,
  84.150 +                                     uint32_t length,
  84.151 +                                     uint32_t pcrindex,
  84.152 +                                     uint32_t *edx_ptr)
  84.153  {
  84.154  	uint32_t rc = 0;
  84.155  	struct hleeo hleeo;
  84.156 @@ -1356,9 +1342,7 @@ void sha1_do(sha1_ctx *ctx, const unsign
  84.157  
  84.158  	/* treat data in 64-byte chunks */
  84.159  	for (offset = 0; length - offset >= 64; offset += 64) {
  84.160 -		/* copy into the 'w' array */
  84.161  		memcpy(w, data32 + offset, 64);
  84.162 -		/* hash the block in the 'w' array */
  84.163  		sha1_block((uint32_t *)w, ctx);
  84.164  		bits += (64 * 8);
  84.165  	}
  84.166 @@ -1408,7 +1392,8 @@ void sha1(const unsigned char *data, uin
  84.167  }
  84.168  
  84.169  
  84.170 -uint32_t TCGInterruptHandler(pushad_regs_t *regs, uint32_t esds, uint32_t flags_ptr)
  84.171 +uint32_t TCGInterruptHandler(pushad_regs_t *regs, uint32_t esds,
  84.172 +                             uint32_t flags_ptr)
  84.173  {
  84.174  	uint16_t DS = esds >> 16;
  84.175  	uint16_t ES = esds & 0xffff;
  84.176 @@ -1435,7 +1420,6 @@ uint32_t TCGInterruptHandler(pushad_regs
  84.177  			}
  84.178  		}
  84.179  		break;
  84.180 -
  84.181  	case 0x01:
  84.182  		regs->u.r32.eax =
  84.183  			HashLogExtendEvent32((struct hleei_short*)
    85.1 --- a/tools/firmware/rombios/32bitgateway.c	Wed Mar 21 17:03:00 2007 -0500
    85.2 +++ b/tools/firmware/rombios/32bitgateway.c	Wed Mar 21 18:08:31 2007 -0500
    85.3 @@ -153,26 +153,17 @@ realmode_gdtdesc:				;to be used in real
    85.4  
    85.5  switch_to_realmode:
    85.6      ; Implementation of switching from protected mode to real mode
    85.7 -    ; restores all registers and prepares cs, es, ds, ss to be used
    85.8 -    ; in real mode
    85.9 +    ; prepares cs, es, ds, ss to be used in real mode
   85.10 +    ; spills   eax
   85.11      START_PM_CODE
   85.12  
   85.13      ; need to fix up the stack to return in 16 bit mode
   85.14      ; currently the 32 bit return address is on the stack
   85.15 -    push bp					;pop@A1
   85.16 -    mov bp, sp
   85.17 -    push eax					;pop@X
   85.18 +    pop eax
   85.19 +    push ax
   85.20  
   85.21 -    mov eax, [bp]				; return address low 16bits
   85.22 -                  				; and 'bp' are being moved
   85.23 -    mov 2[bp], eax
   85.24 -
   85.25 -    pop eax					;@X
   85.26 -    add sp, #2					; adjust stack for 'lost' bytes
   85.27 -
   85.28 -    push eax					;pop@1
   85.29 -    push bx					;pop@2
   85.30 -    push si					;pop@3
   85.31 +    push bx					;pop@1
   85.32 +    push si					;pop@2
   85.33  
   85.34      call _ebda_ss_offset32			; get the offset of the ss
   85.35      mov bx, ax					; entry within the ebda.
   85.36 @@ -229,10 +220,8 @@ switch_to_realmode_goon_2:
   85.37  
   85.38      sti						; allow interrupts
   85.39  
   85.40 -    pop si					;@3
   85.41 -    pop bx					;@2
   85.42 -    pop eax					;@1
   85.43 -    pop bp					;@A1
   85.44 +    pop si					;@2
   85.45 +    pop bx					;@1
   85.46  
   85.47      ret
   85.48  
    86.1 --- a/tools/firmware/rombios/rombios.c	Wed Mar 21 17:03:00 2007 -0500
    86.2 +++ b/tools/firmware/rombios/rombios.c	Wed Mar 21 18:08:31 2007 -0500
    86.3 @@ -4196,178 +4196,86 @@ ASM_END
    86.4      case 0xe8:
    86.5          switch(regs.u.r8.al)
    86.6          {
    86.7 -         case 0x20: // coded by osmaker aka K.J.
    86.8 -            if(regs.u.r32.edx == 0x534D4150) /* SMAP */
    86.9 -            {
   86.10 -#ifdef HVMASSIST
   86.11 -		if ((regs.u.r16.bx / 0x14) * 0x14 == regs.u.r16.bx) {
   86.12 -		    Bit16u e820_table_size = read_word(0xe000, 0x8) * 0x14;
   86.13 -
   86.14 -		    if (regs.u.r16.bx + 0x14 <= e820_table_size) {
   86.15 -			memcpyb(ES, regs.u.r16.di,
   86.16 -				0xe000, 0x10 + regs.u.r16.bx, 0x14);
   86.17 -		    }
   86.18 -		    regs.u.r32.ebx += 0x14;
   86.19 -		    if ((regs.u.r32.ebx + 0x14 - 1) > e820_table_size)
   86.20 -			regs.u.r32.ebx = 0;
   86.21 -		    regs.u.r32.eax = 0x534D4150;
   86.22 -		    regs.u.r32.ecx = 0x14;
   86.23 -		    CLEAR_CF();
   86.24 -		    return;
   86.25 -		} else if (regs.u.r16.bx == 1) {
   86.26 -		    extended_memory_size = inb_cmos(0x35);
   86.27 -		    extended_memory_size <<= 8;
   86.28 -		    extended_memory_size |= inb_cmos(0x34);
   86.29 -		    extended_memory_size *= 64;
   86.30 -		    if (extended_memory_size > 0x3bc000) // greater than EFF00000???
   86.31 -		    {
   86.32 -			extended_memory_size = 0x3bc000; // everything after this is reserved memory until we get to 0x100000000
   86.33 -		    }
   86.34 -		    extended_memory_size *= 1024;
   86.35 -		    extended_memory_size += 15728640; // make up for the 16mb of memory that is chopped off
   86.36 -
   86.37 -		    if (extended_memory_size <= 15728640)
   86.38 -		    {
   86.39 -			extended_memory_size = inb_cmos(0x31);
   86.40 -			extended_memory_size <<= 8;
   86.41 -			extended_memory_size |= inb_cmos(0x30);
   86.42 -			extended_memory_size *= 1024;
   86.43 -		    }
   86.44 -
   86.45 -		    write_word(ES, regs.u.r16.di, 0x0000);
   86.46 -		    write_word(ES, regs.u.r16.di+2, 0x0010);
   86.47 -		    write_word(ES, regs.u.r16.di+4, 0x0000);
   86.48 -		    write_word(ES, regs.u.r16.di+6, 0x0000);
   86.49 -
   86.50 -		    write_word(ES, regs.u.r16.di+8, extended_memory_size);
   86.51 -		    extended_memory_size >>= 16;
   86.52 -		    write_word(ES, regs.u.r16.di+10, extended_memory_size);
   86.53 -		    extended_memory_size >>= 16;
   86.54 -		    write_word(ES, regs.u.r16.di+12, extended_memory_size);
   86.55 -		    extended_memory_size >>= 16;
   86.56 -		    write_word(ES, regs.u.r16.di+14, extended_memory_size);
   86.57 -
   86.58 -		    write_word(ES, regs.u.r16.di+16, 0x1);
   86.59 -		    write_word(ES, regs.u.r16.di+18, 0x0);
   86.60 -
   86.61 -		    regs.u.r32.ebx = 0;
   86.62 -		    regs.u.r32.eax = 0x534D4150;
   86.63 -		    regs.u.r32.ecx = 0x14;
   86.64 -		    CLEAR_CF();
   86.65 -		    return;
   86.66 -		} else { /* AX=E820, DX=534D4150, BX unrecognized */
   86.67 -		    goto int15_unimplemented;
   86.68 -		}
   86.69 -#else
   86.70 -                switch(regs.u.r16.bx)
   86.71 -                {
   86.72 -                    case 0:
   86.73 -                        write_word(ES, regs.u.r16.di, 0x00);
   86.74 -                        write_word(ES, regs.u.r16.di+2, 0x00);
   86.75 -                        write_word(ES, regs.u.r16.di+4, 0x00);
   86.76 -                        write_word(ES, regs.u.r16.di+6, 0x00);
   86.77 -
   86.78 -                        write_word(ES, regs.u.r16.di+8, 0xFC00);
   86.79 -                        write_word(ES, regs.u.r16.di+10, 0x0009);
   86.80 -                        write_word(ES, regs.u.r16.di+12, 0x0000);
   86.81 -                        write_word(ES, regs.u.r16.di+14, 0x0000);
   86.82 -
   86.83 -                        write_word(ES, regs.u.r16.di+16, 0x1);
   86.84 -                        write_word(ES, regs.u.r16.di+18, 0x0);
   86.85 -
   86.86 -                        regs.u.r32.ebx = 1;
   86.87 -
   86.88 -                        regs.u.r32.eax = 0x534D4150;
   86.89 -                        regs.u.r32.ecx = 0x14;
   86.90 -                        CLEAR_CF();
   86.91 -                        return;
   86.92 -                        break;
   86.93 -                    case 1:
   86.94 -                        extended_memory_size = inb_cmos(0x35);
   86.95 -                        extended_memory_size <<= 8;
   86.96 -                        extended_memory_size |= inb_cmos(0x34);
   86.97 -                        extended_memory_size *= 64;
   86.98 -                        if(extended_memory_size > 0x3bc000) // greater than EFF00000???
   86.99 -                        {
  86.100 -                            extended_memory_size = 0x3bc000; // everything after this is reserved memory until we get to 0x100000000
  86.101 -                        }
  86.102 -                        extended_memory_size *= 1024;
  86.103 -                        extended_memory_size += 15728640; // make up for the 16mb of memory that is chopped off
  86.104 -
  86.105 -                        if(extended_memory_size <= 15728640)
  86.106 -                        {
  86.107 -                            extended_memory_size = inb_cmos(0x31);
  86.108 -                            extended_memory_size <<= 8;
  86.109 -                            extended_memory_size |= inb_cmos(0x30);
  86.110 -                            extended_memory_size *= 1024;
  86.111 -                        }
  86.112 -
  86.113 -                        write_word(ES, regs.u.r16.di, 0x0000);
  86.114 -                        write_word(ES, regs.u.r16.di+2, 0x0010);
  86.115 -                        write_word(ES, regs.u.r16.di+4, 0x0000);
  86.116 -                        write_word(ES, regs.u.r16.di+6, 0x0000);
  86.117 -
  86.118 -                        write_word(ES, regs.u.r16.di+8, extended_memory_size);
  86.119 -                        extended_memory_size >>= 16;
  86.120 -                        write_word(ES, regs.u.r16.di+10, extended_memory_size);
  86.121 -                        extended_memory_size >>= 16;
  86.122 -                        write_word(ES, regs.u.r16.di+12, extended_memory_size);
  86.123 -                        extended_memory_size >>= 16;
  86.124 -                        write_word(ES, regs.u.r16.di+14, extended_memory_size);
  86.125 -
  86.126 -                        write_word(ES, regs.u.r16.di+16, 0x1);
  86.127 -                        write_word(ES, regs.u.r16.di+18, 0x0);
  86.128 -
  86.129 -                        regs.u.r32.ebx = 0;
  86.130 -                        regs.u.r32.eax = 0x534D4150;
  86.131 -                        regs.u.r32.ecx = 0x14;
  86.132 -                        CLEAR_CF();
  86.133 -                        return;
  86.134 -                        break;
  86.135 -                    default:  /* AX=E820, DX=534D4150, BX unrecognized */
  86.136 -                        goto int15_unimplemented;
  86.137 +        case 0x20: {
  86.138 +            Bit16u e820_table_size = read_word(0xe000, 0x8) * 0x14;
  86.139 +
  86.140 +            if (regs.u.r32.edx != 0x534D4150) /* SMAP */
  86.141 +                goto int15_unimplemented;
  86.142 +
  86.143 +            if ((regs.u.r16.bx / 0x14) * 0x14 == regs.u.r16.bx) {
  86.144 +                if (regs.u.r16.bx + 0x14 <= e820_table_size)
  86.145 +                    memcpyb(ES, regs.u.r16.di,
  86.146 +                            0xe000, 0x10 + regs.u.r16.bx, 0x14);
  86.147 +                regs.u.r32.ebx += 0x14;
  86.148 +                if ((regs.u.r32.ebx + 0x14 - 1) > e820_table_size)
  86.149 +                    regs.u.r32.ebx = 0;
  86.150 +            } else if (regs.u.r16.bx == 1) {
  86.151 +                Bit32u base, type;
  86.152 +                Bit16u off;
  86.153 +                for (off = 0; off < e820_table_size; off += 0x14) {
  86.154 +                    base = read_dword(0xe000, 0x10 + off);
  86.155 +                    type = read_dword(0xe000, 0x20 + off);
  86.156 +                    if ((base >= 0x100000) && (type == 1))
  86.157                          break;
  86.158                  }
  86.159 -#endif
  86.160 -	    } else {
  86.161 -	      // if DX != 0x534D4150)
  86.162 -	      goto int15_unimplemented;
  86.163 -	    }
  86.164 +                if (off == e820_table_size) {
  86.165 +                    SET_CF();
  86.166 +                    break;
  86.167 +                }
  86.168 +                memcpyb(ES, regs.u.r16.di, 0xe000, 0x10 + off, 0x14);
  86.169 +                regs.u.r32.ebx = 0;
  86.170 +            } else { /* AX=E820, DX=534D4150, BX unrecognized */
  86.171 +                goto int15_unimplemented;
  86.172 +            }
  86.173 +
  86.174 +            regs.u.r32.eax = 0x534D4150;
  86.175 +            regs.u.r32.ecx = 0x14;
  86.176 +            CLEAR_CF();
  86.177              break;
  86.178 -
  86.179 -        case 0x01: 
  86.180 -          // do we have any reason to fail here ?
  86.181 -          CLEAR_CF();
  86.182 -
  86.183 -          // my real system sets ax and bx to 0
  86.184 -          // this is confirmed by Ralph Brown list
  86.185 -          // but syslinux v1.48 is known to behave 
  86.186 -          // strangely if ax is set to 0
  86.187 -          // regs.u.r16.ax = 0;
  86.188 -          // regs.u.r16.bx = 0;
  86.189 -
  86.190 -          // Get the amount of extended memory (above 1M)
  86.191 -          regs.u.r8.cl = inb_cmos(0x30);
  86.192 -          regs.u.r8.ch = inb_cmos(0x31);
  86.193 +        }
  86.194 +
  86.195 +        case 0x01: {
  86.196 +            Bit16u off, e820_table_size = read_word(0xe000, 0x8) * 0x14;
  86.197 +            Bit32u base, type, size;
  86.198 +
  86.199 +            // do we have any reason to fail here ?
  86.200 +            CLEAR_CF();
  86.201 +
  86.202 +            // Get the amount of extended memory (above 1M)
  86.203 +            regs.u.r8.cl = inb_cmos(0x30);
  86.204 +            regs.u.r8.ch = inb_cmos(0x31);
  86.205            
  86.206 -          // limit to 15M
  86.207 -          if(regs.u.r16.cx > 0x3c00)
  86.208 -          {
  86.209 -            regs.u.r16.cx = 0x3c00;
  86.210 -          }
  86.211 -
  86.212 -          // Get the amount of extended memory above 16M in 64k blocs
  86.213 -          regs.u.r8.dl = inb_cmos(0x34);
  86.214 -          regs.u.r8.dh = inb_cmos(0x35);
  86.215 -
  86.216 -          // Set configured memory equal to extended memory
  86.217 -          regs.u.r16.ax = regs.u.r16.cx;
  86.218 -          regs.u.r16.bx = regs.u.r16.dx;
  86.219 -          break;
  86.220 +            // limit to 15M
  86.221 +            if (regs.u.r16.cx > (15*1024))
  86.222 +                regs.u.r16.cx = 15*1024;
  86.223 +
  86.224 +            // Find first RAM E820 entry >= 1MB.
  86.225 +            for (off = 0; off < e820_table_size; off += 0x14) {
  86.226 +                base = read_dword(0xe000, 0x10 + off);
  86.227 +                type = read_dword(0xe000, 0x20 + off);
  86.228 +                if ((base >= 0x100000) && (type == 1))
  86.229 +                    break;
  86.230 +            }
  86.231 +
  86.232 +            // If there is RAM above 16MB, return amount in 64kB chunks.
  86.233 +            regs.u.r16.dx = 0;
  86.234 +            if (off != e820_table_size) {
  86.235 +                size = base + read_dword(0xe000, 0x18 + off);
  86.236 +                if (size > 0x1000000) {
  86.237 +                    size -= 0x1000000;
  86.238 +                    regs.u.r16.dx = (Bit16u)(size >> 16);
  86.239 +                }
  86.240 +            }
  86.241 +
  86.242 +            // Set configured memory equal to extended memory
  86.243 +            regs.u.r16.ax = regs.u.r16.cx;
  86.244 +            regs.u.r16.bx = regs.u.r16.dx;
  86.245 +            break;
  86.246 +        }
  86.247  	default:  /* AH=0xE8?? but not implemented */
  86.248 -	  goto int15_unimplemented;
  86.249 -       }
  86.250 -       break;
  86.251 +            goto int15_unimplemented;
  86.252 +        }
  86.253 +        break;
  86.254      int15_unimplemented:
  86.255         // fall into the default
  86.256      default:
  86.257 @@ -7792,10 +7700,11 @@ ASM_END
  86.258  
  86.259      bootdrv = (Bit8u)(status>>8);
  86.260      bootseg = read_word(ebda_seg,&EbdaData->cdemu.load_segment);
  86.261 -    /* Canonicalize bootseg:bootip */
  86.262  #if BX_TCGBIOS
  86.263      tcpa_add_bootdevice((Bit32u)1L, (Bit32u)0L);
  86.264  #endif
  86.265 +
  86.266 +    /* Canonicalize bootseg:bootip */
  86.267      bootip = (bootseg & 0x0fff) << 4;
  86.268      bootseg &= 0xf000;
  86.269      break;
  86.270 @@ -7812,8 +7721,6 @@ ASM_END
  86.271  #if BX_TCGBIOS
  86.272    tcpa_ipl((Bit32u)bootseg);               /* specs: 8.2.3 steps 4 and 5 */
  86.273  #endif
  86.274 -  /* Debugging info */
  86.275 -  printf("Booting from %x:%x\n", bootseg, bootip);
  86.276    
  86.277    /* Jump to the boot vector */
  86.278  ASM_START
    87.1 --- a/tools/firmware/rombios/tcgbios.c	Wed Mar 21 17:03:00 2007 -0500
    87.2 +++ b/tools/firmware/rombios/tcgbios.c	Wed Mar 21 18:08:31 2007 -0500
    87.3 @@ -228,6 +228,8 @@ int1a_function32(regs, ES, DS, FLAGS)
    87.4  {
    87.5  	Bit16u rc;
    87.6  
    87.7 +	BX_DEBUG_INT1A("int1a_32: AX=%04x\n", regs.u.r16.ax);
    87.8 +
    87.9  	switch (regs.u.r8.ah) {
   87.10  	case 0xbb:
   87.11  		/*
   87.12 @@ -256,8 +258,10 @@ int1a_function32(regs, ES, DS, FLAGS)
   87.13  		default:
   87.14  			SET_CF();
   87.15  		}
   87.16 +		break;
   87.17  	default:
   87.18  		SET_CF();
   87.19  		break;
   87.20  	}
   87.21 +	BX_DEBUG_INT1A("int1a_32: FLAGS=%04x\n", FLAGS);
   87.22  }
    88.1 --- a/tools/ioemu/hw/ide.c	Wed Mar 21 17:03:00 2007 -0500
    88.2 +++ b/tools/ioemu/hw/ide.c	Wed Mar 21 18:08:31 2007 -0500
    88.3 @@ -396,17 +396,41 @@ typedef struct PCIIDEState {
    88.4  
    88.5  #ifdef DMA_MULTI_THREAD
    88.6  
    88.7 +static pthread_t ide_dma_thread;
    88.8  static int file_pipes[2];
    88.9  
   88.10  static void ide_dma_loop(BMDMAState *bm);
   88.11  static void dma_thread_loop(BMDMAState *bm);
   88.12  
   88.13 +extern int suspend_requested;
   88.14  static void *dma_thread_func(void* opaque)
   88.15  {
   88.16      BMDMAState* req;
   88.17 +    fd_set fds;
   88.18 +    int rv, nfds = file_pipes[0] + 1;
   88.19 +    struct timeval tm;
   88.20  
   88.21 -    while (read(file_pipes[0], &req, sizeof(req))) {
   88.22 -        dma_thread_loop(req);
   88.23 +    while (1) {
   88.24 +
   88.25 +        /* Wait at most a second for the pipe to become readable */
   88.26 +        FD_ZERO(&fds);
   88.27 +        FD_SET(file_pipes[0], &fds);
   88.28 +        tm.tv_sec = 1;
   88.29 +        tm.tv_usec = 0;
   88.30 +        rv = select(nfds, &fds, NULL, NULL, &tm);
   88.31 +        
   88.32 +        if (rv != 0) {
   88.33 +            if (read(file_pipes[0], &req, sizeof(req)) == 0)
   88.34 +                return NULL;
   88.35 +            dma_thread_loop(req);
   88.36 +        } else {
   88.37 +            if (suspend_requested)  {
   88.38 +                /* Need to tidy up the DMA thread so that we don't end up 
   88.39 +                 * finishing operations after the domain's ioreqs are 
   88.40 +                 * drained and its state saved */
   88.41 +                return NULL;
   88.42 +            }
   88.43 +        }
   88.44      }
   88.45  
   88.46      return NULL;
   88.47 @@ -414,24 +438,41 @@ static void *dma_thread_func(void* opaqu
   88.48  
   88.49  static void dma_create_thread(void)
   88.50  {
   88.51 -    pthread_t tid;
   88.52      int rt;
   88.53 +    pthread_attr_t a;
   88.54  
   88.55      if (pipe(file_pipes) != 0) {
   88.56          fprintf(stderr, "create pipe failed\n");
   88.57          exit(1);
   88.58      }
   88.59  
   88.60 -    if ((rt = pthread_create(&tid, NULL, dma_thread_func, NULL))) {
   88.61 +    if ((rt = pthread_attr_init(&a))
   88.62 +        || (rt = pthread_attr_setdetachstate(&a, PTHREAD_CREATE_JOINABLE))) {
   88.63 +        fprintf(stderr, "Oops, dma thread attr setup failed, errno=%d\n", rt);
   88.64 +        exit(1);
   88.65 +    }    
   88.66 +    
   88.67 +    if ((rt = pthread_create(&ide_dma_thread, &a, dma_thread_func, NULL))) {
   88.68          fprintf(stderr, "Oops, dma thread creation failed, errno=%d\n", rt);
   88.69          exit(1);
   88.70      }
   88.71 +}
   88.72  
   88.73 -    if ((rt = pthread_detach(tid))) {
   88.74 -        fprintf(stderr, "Oops, dma thread detachment failed, errno=%d\n", rt);
   88.75 -        exit(1);
   88.76 +void ide_stop_dma_thread(void)
   88.77 +{
   88.78 +    int rc;
   88.79 +    /* Make sure the IDE DMA thread is stopped */
   88.80 +    if ( (rc = pthread_join(ide_dma_thread, NULL)) != 0 )
   88.81 +    {
   88.82 +        fprintf(stderr, "Oops, error collecting IDE DMA thread (%s)\n", 
   88.83 +                strerror(rc));
   88.84      }
   88.85  }
   88.86 +
   88.87 +#else
   88.88 +void ide_stop_dma_thread(void)
   88.89 +{
   88.90 +}
   88.91  #endif /* DMA_MULTI_THREAD */
   88.92  
   88.93  #if defined(__ia64__)
    89.1 --- a/tools/ioemu/hw/usb-hid.c	Wed Mar 21 17:03:00 2007 -0500
    89.2 +++ b/tools/ioemu/hw/usb-hid.c	Wed Mar 21 18:08:31 2007 -0500
    89.3 @@ -517,6 +517,49 @@ static void usb_mouse_handle_destroy(USB
    89.4      qemu_free(s);
    89.5  }
    89.6  
    89.7 +void usb_mouse_save(QEMUFile *f, void *opaque)
    89.8 +{
    89.9 +    USBMouseState *s = (USBMouseState*)opaque;
   89.10 +
   89.11 +    qemu_put_be32s(f, &s->dx);
   89.12 +    qemu_put_be32s(f, &s->dy);
   89.13 +    qemu_put_be32s(f, &s->dz);
   89.14 +    qemu_put_be32s(f, &s->buttons_state);
   89.15 +    qemu_put_be32s(f, &s->x);
   89.16 +    qemu_put_be32s(f, &s->y);
   89.17 +    qemu_put_be32s(f, &s->kind);
   89.18 +    qemu_put_be32s(f, &s->mouse_grabbed);
   89.19 +    qemu_put_be32s(f, &s->status_changed);
   89.20 +
   89.21 +}
   89.22 +
   89.23 +int usb_mouse_load(QEMUFile *f, void *opaque, int version_id)
   89.24 +{
   89.25 +    USBMouseState *s = (USBMouseState*)opaque;
   89.26 +
   89.27 +    if (version_id != 1)
   89.28 +        return -EINVAL;
   89.29 +
   89.30 +    qemu_get_be32s(f, &s->dx);
   89.31 +    qemu_get_be32s(f, &s->dy);
   89.32 +    qemu_get_be32s(f, &s->dz);
   89.33 +    qemu_get_be32s(f, &s->buttons_state);
   89.34 +    qemu_get_be32s(f, &s->x);
   89.35 +    qemu_get_be32s(f, &s->y);
   89.36 +    qemu_get_be32s(f, &s->kind);
   89.37 +    qemu_get_be32s(f, &s->mouse_grabbed);
   89.38 +    qemu_get_be32s(f, &s->status_changed);
   89.39 +
   89.40 +    if ( s->kind == USB_TABLET) {
   89.41 +        fprintf(logfile, "usb_mouse_load:add usb_tablet_event.\n");
   89.42 +        qemu_add_mouse_event_handler(usb_tablet_event, s, 1);
   89.43 +    } else if ( s->kind == USB_MOUSE) {
   89.44 +        fprintf(logfile, "usb_mouse_load:add usb_mouse_event.\n");
   89.45 +        qemu_add_mouse_event_handler(usb_mouse_event, s, 0);
   89.46 +    }
   89.47 +}
   89.48 +
   89.49 +
   89.50  USBDevice *usb_tablet_init(void)
   89.51  {
   89.52      USBMouseState *s;
   89.53 @@ -536,6 +579,8 @@ USBDevice *usb_tablet_init(void)
   89.54  
   89.55      pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Tablet");
   89.56  
   89.57 +    register_savevm("USB tablet dev", 0, 1, usb_mouse_save, usb_mouse_load, s);
   89.58 +
   89.59      return (USBDevice *)s;
   89.60  }
   89.61  
   89.62 @@ -558,5 +603,7 @@ USBDevice *usb_mouse_init(void)
   89.63  
   89.64      pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Mouse");
   89.65  
   89.66 +    register_savevm("USB mouse dev", 0, 1, usb_mouse_save, usb_mouse_load, s);
   89.67 +
   89.68      return (USBDevice *)s;
   89.69  }
    90.1 --- a/tools/ioemu/hw/usb-ohci.c	Wed Mar 21 17:03:00 2007 -0500
    90.2 +++ b/tools/ioemu/hw/usb-ohci.c	Wed Mar 21 18:08:31 2007 -0500
    90.3 @@ -1186,5 +1186,7 @@ void usb_ohci_init(struct PCIBus *bus, i
    90.4          qemu_register_usb_port(&ohci->rhport[i].port, ohci, i, ohci_attach);
    90.5      }
    90.6  
    90.7 +    register_savevm("OHCI USB", 0, 1, generic_pci_save, generic_pci_load, ohci);
    90.8 +
    90.9      ohci_reset(ohci);
   90.10  }
    91.1 --- a/tools/ioemu/hw/usb-uhci.c	Wed Mar 21 17:03:00 2007 -0500
    91.2 +++ b/tools/ioemu/hw/usb-uhci.c	Wed Mar 21 18:08:31 2007 -0500
    91.3 @@ -658,6 +658,50 @@ static void uhci_map(PCIDevice *pci_dev,
    91.4      register_ioport_read(addr, 32, 1, uhci_ioport_readb, s);
    91.5  }
    91.6  
    91.7 +void uhci_usb_save(QEMUFile *f, void *opaque)
    91.8 +{
    91.9 +    int i;
   91.10 +    UHCIState *s = (UHCIState*)opaque;
   91.11 +
   91.12 +    qemu_put_be16s(f, &s->cmd);
   91.13 +    qemu_put_be16s(f, &s->status);
   91.14 +    qemu_put_be16s(f, &s->intr);
   91.15 +    qemu_put_be16s(f, &s->frnum);
   91.16 +    qemu_put_be32s(f, &s->fl_base_addr);
   91.17 +    qemu_put_8s(f, &s->sof_timing);
   91.18 +    qemu_put_8s(f, &s->status2);
   91.19 +
   91.20 +    for(i = 0; i < NB_PORTS; i++) {
   91.21 +        qemu_put_be16s(f, &s->ports[i].ctrl);
   91.22 +    }
   91.23 +
   91.24 +    qemu_put_timer(f, s->frame_timer);
   91.25 +}
   91.26 +
   91.27 +int uhci_usb_load(QEMUFile *f, void *opaque, int version_id)
   91.28 +{
   91.29 +    int i;
   91.30 +    UHCIState *s = (UHCIState*)opaque;
   91.31 +
   91.32 +    if (version_id != 1)
   91.33 +        return -EINVAL;
   91.34 +
   91.35 +    qemu_get_be16s(f, &s->cmd);
   91.36 +    qemu_get_be16s(f, &s->status);
   91.37 +    qemu_get_be16s(f, &s->intr);
   91.38 +    qemu_get_be16s(f, &s->frnum);
   91.39 +    qemu_get_be32s(f, &s->fl_base_addr);
   91.40 +    qemu_get_8s(f, &s->sof_timing);
   91.41 +    qemu_get_8s(f, &s->status2);
   91.42 +
   91.43 +    for(i = 0; i < NB_PORTS; i++) {
   91.44 +        qemu_get_be16s(f, &s->ports[i].ctrl);
   91.45 +    }
   91.46 +
   91.47 +    qemu_get_timer(f, s->frame_timer);
   91.48 +
   91.49 +}
   91.50 +
   91.51  void usb_uhci_init(PCIBus *bus, int devfn)
   91.52  {
   91.53      UHCIState *s;
   91.54 @@ -693,4 +737,8 @@ void usb_uhci_init(PCIBus *bus, int devf
   91.55         to rely on this.  */
   91.56      pci_register_io_region(&s->dev, 4, 0x20, 
   91.57                             PCI_ADDRESS_SPACE_IO, uhci_map);
   91.58 +
   91.59 +    register_savevm("UHCI_usb_pci", 0, 1, generic_pci_save, generic_pci_load, s);
   91.60 +
   91.61 +    register_savevm("UHCI usb controller", 0, 1, uhci_usb_save, uhci_usb_load, s);
   91.62  }
    92.1 --- a/tools/ioemu/hw/usb.c	Wed Mar 21 17:03:00 2007 -0500
    92.2 +++ b/tools/ioemu/hw/usb.c	Wed Mar 21 18:08:31 2007 -0500
    92.3 @@ -191,3 +191,43 @@ int set_usb_string(uint8_t *buf, const c
    92.4      }
    92.5      return q - buf;
    92.6  }
    92.7 +
    92.8 +void generic_usb_save(QEMUFile* f, void *opaque)
    92.9 +{
   92.10 +    USBDevice *s = (USBDevice*)opaque;
   92.11 +
   92.12 +    qemu_put_be32s(f, &s->speed);
   92.13 +    qemu_put_8s(f, &s->addr);
   92.14 +    qemu_put_be32s(f, &s->state);
   92.15 +
   92.16 +    qemu_put_buffer(f, s->setup_buf, 8);
   92.17 +    qemu_put_buffer(f, s->data_buf, 1024);
   92.18 +
   92.19 +    qemu_put_be32s(f, &s->remote_wakeup);
   92.20 +    qemu_put_be32s(f, &s->setup_state);
   92.21 +    qemu_put_be32s(f, &s->setup_len);
   92.22 +    qemu_put_be32s(f, &s->setup_index);
   92.23 +
   92.24 +}
   92.25 +
   92.26 +int generic_usb_load(QEMUFile* f, void *opaque, int version_id)
   92.27 +{
   92.28 +    USBDevice *s = (USBDevice*)opaque;
   92.29 +
   92.30 +    if (version_id != 1)
   92.31 +        return -EINVAL;
   92.32 +
   92.33 +    qemu_get_be32s(f, &s->speed);
   92.34 +    qemu_get_8s(f, &s->addr);
   92.35 +    qemu_get_be32s(f, &s->state);
   92.36 +
   92.37 +    qemu_get_buffer(f, s->setup_buf, 8);
   92.38 +    qemu_get_buffer(f, s->data_buf, 1024);
   92.39 +
   92.40 +    qemu_get_be32s(f, &s->remote_wakeup);
   92.41 +    qemu_get_be32s(f, &s->setup_state);
   92.42 +    qemu_get_be32s(f, &s->setup_len);
   92.43 +    qemu_get_be32s(f, &s->setup_index);
   92.44 +
   92.45 +    return 0;
   92.46 +}
    93.1 --- a/tools/ioemu/hw/usb.h	Wed Mar 21 17:03:00 2007 -0500
    93.2 +++ b/tools/ioemu/hw/usb.h	Wed Mar 21 18:08:31 2007 -0500
    93.3 @@ -176,3 +176,9 @@ USBDevice *usb_tablet_init(void);
    93.4  
    93.5  /* usb-msd.c */
    93.6  USBDevice *usb_msd_init(const char *filename);
    93.7 +
    93.8 +/* usb.c */
    93.9 +void generic_usb_save(QEMUFile* f, void *opaque);
   93.10 +int generic_usb_load(QEMUFile* f, void *opaque, int version_id);
   93.11 +
   93.12 +
    94.1 --- a/tools/ioemu/target-i386-dm/exec-dm.c	Wed Mar 21 17:03:00 2007 -0500
    94.2 +++ b/tools/ioemu/target-i386-dm/exec-dm.c	Wed Mar 21 18:08:31 2007 -0500
    94.3 @@ -450,6 +450,9 @@ static inline int paddr_is_ram(target_ph
    94.4  #define phys_ram_addr(x) (phys_ram_base + (x))
    94.5  #endif
    94.6  
    94.7 +extern unsigned long *logdirty_bitmap;
    94.8 +extern unsigned long logdirty_bitmap_size;
    94.9 +
   94.10  void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, 
   94.11                              int len, int is_write)
   94.12  {
   94.13 @@ -485,9 +488,20 @@ void cpu_physical_memory_rw(target_phys_
   94.14                      l = 1;
   94.15                  }
   94.16              } else if (paddr_is_ram(addr)) {
   94.17 -                /* Reading from RAM */
   94.18 +                /* Writing to RAM */
   94.19                  ptr = phys_ram_addr(addr);
   94.20                  memcpy(ptr, buf, l);
   94.21 +                if (logdirty_bitmap != NULL) {
   94.22 +                    /* Record that we have dirtied this frame */
   94.23 +                    unsigned long pfn = addr >> TARGET_PAGE_BITS;
   94.24 +                    if (pfn / 8 >= logdirty_bitmap_size) {
   94.25 +                        fprintf(logfile, "dirtying pfn %x >= bitmap size %x\n",
   94.26 +                                pfn, logdirty_bitmap_size * 8);
   94.27 +                    } else {
   94.28 +                        logdirty_bitmap[pfn / HOST_LONG_BITS]
   94.29 +                            |= 1UL << pfn % HOST_LONG_BITS;
   94.30 +                    }
   94.31 +                }
   94.32  #ifdef __ia64__
   94.33                  sync_icache(ptr, l);
   94.34  #endif 
    95.1 --- a/tools/ioemu/target-i386-dm/helper2.c	Wed Mar 21 17:03:00 2007 -0500
    95.2 +++ b/tools/ioemu/target-i386-dm/helper2.c	Wed Mar 21 18:08:31 2007 -0500
    95.3 @@ -439,6 +439,18 @@ void cpu_ioreq_xor(CPUState *env, ioreq_
    95.4      req->data = tmp1;
    95.5  }
    95.6  
    95.7 +void cpu_ioreq_xchg(CPUState *env, ioreq_t *req)
    95.8 +{
    95.9 +    unsigned long tmp1;
   95.10 +
   95.11 +    if (req->data_is_ptr != 0)
   95.12 +        hw_error("expected scalar value");
   95.13 +
   95.14 +    read_physical(req->addr, req->size, &tmp1);
   95.15 +    write_physical(req->addr, req->size, &req->data);
   95.16 +    req->data = tmp1;
   95.17 +}
   95.18 +
   95.19  void __handle_ioreq(CPUState *env, ioreq_t *req)
   95.20  {
   95.21      if (!req->data_is_ptr && req->dir == IOREQ_WRITE && req->size != 4)
   95.22 @@ -463,6 +475,9 @@ void __handle_ioreq(CPUState *env, ioreq
   95.23      case IOREQ_TYPE_XOR:
   95.24          cpu_ioreq_xor(env, req);
   95.25          break;
   95.26 +    case IOREQ_TYPE_XCHG:
   95.27 +        cpu_ioreq_xchg(env, req);
   95.28 +        break;
   95.29      default:
   95.30          hw_error("Invalid ioreq type 0x%x\n", req->type);
   95.31      }
   95.32 @@ -577,7 +592,28 @@ int main_loop(void)
   95.33          destroy_hvm_domain();
   95.34      else {
   95.35          char qemu_file[20];
   95.36 +        ioreq_t *req;
   95.37 +        int rc;
   95.38 +
   95.39          sprintf(qemu_file, "/tmp/xen.qemu-dm.%d", domid);
   95.40 +        xc_domain_pause(xc_handle, domid);
   95.41 +
   95.42 +        /* Pull all outstanding ioreqs through the system */
   95.43 +        handle_buffered_io(env);
   95.44 +        main_loop_wait(1); /* For the select() on events */
   95.45 +        
   95.46 +        /* Stop the IDE thread */
   95.47 +        ide_stop_dma_thread();
   95.48 +
   95.49 +        /* Make sure that all outstanding IO responses are handled too */ 
   95.50 +        if ( xc_hvm_drain_io(xc_handle, domid) != 0 )
   95.51 +        {
   95.52 +            fprintf(stderr, "error clearing ioreq rings (%s)\n", 
   95.53 +                    strerror(errno));
   95.54 +            return -1;
   95.55 +        }
   95.56 +
   95.57 +        /* Save the device state */
   95.58          if (qemu_savevm(qemu_file) < 0)
   95.59              fprintf(stderr, "qemu save fail.\n");
   95.60      }
    96.1 --- a/tools/ioemu/vl.c	Wed Mar 21 17:03:00 2007 -0500
    96.2 +++ b/tools/ioemu/vl.c	Wed Mar 21 18:08:31 2007 -0500
    96.3 @@ -841,10 +841,22 @@ void qemu_get_timer(QEMUFile *f, QEMUTim
    96.4  #ifdef CONFIG_DM
    96.5  static void timer_save(QEMUFile *f, void *opaque)
    96.6  {
    96.7 +    /* need timer for save/restoe qemu_timer in usb_uhci */
    96.8 +    if (cpu_ticks_enabled) {
    96.9 +        hw_error("cannot save state if virtual timers are running");
   96.10 +    }
   96.11 +    qemu_put_be64s(f, &cpu_clock_offset);
   96.12  }
   96.13  
   96.14  static int timer_load(QEMUFile *f, void *opaque, int version_id)
   96.15  {
   96.16 +    if (version_id != 1)
   96.17 +        return -EINVAL;
   96.18 +    if (cpu_ticks_enabled) {
   96.19 +        return -EINVAL;
   96.20 +    }
   96.21 +
   96.22 +    qemu_get_be64s(f, &cpu_clock_offset);
   96.23      return 0;
   96.24  }
   96.25  #else  /* !CONFIG_DM */
   96.26 @@ -3900,6 +3912,7 @@ static int usb_device_add(const char *de
   96.27      const char *p;
   96.28      USBDevice *dev;
   96.29      USBPort *port;
   96.30 +    char usb_name[256] = "USB ";
   96.31  
   96.32      if (!free_usb_ports)
   96.33          return -1;
   96.34 @@ -3936,6 +3949,12 @@ static int usb_device_add(const char *de
   96.35      free_usb_ports = port->next;
   96.36      port->next = used_usb_ports;
   96.37      used_usb_ports = port;
   96.38 +
   96.39 +    pstrcpy(usb_name + strlen(usb_name), 
   96.40 +            sizeof(usb_name) - strlen(usb_name), 
   96.41 +            devname);
   96.42 +    register_savevm(usb_name, 0, 1, generic_usb_save, generic_usb_load, dev);
   96.43 +    
   96.44      usb_attach(port, dev);
   96.45      return 0;
   96.46  }
    97.1 --- a/tools/ioemu/vl.h	Wed Mar 21 17:03:00 2007 -0500
    97.2 +++ b/tools/ioemu/vl.h	Wed Mar 21 18:08:31 2007 -0500
    97.3 @@ -843,6 +843,7 @@ void pci_cmd646_ide_init(PCIBus *bus, Bl
    97.4  void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn);
    97.5  int pmac_ide_init (BlockDriverState **hd_table,
    97.6                     SetIRQFunc *set_irq, void *irq_opaque, int irq);
    97.7 +void ide_stop_dma_thread(void);
    97.8  
    97.9  /* cdrom.c */
   97.10  int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track);
    98.1 --- a/tools/ioemu/xenstore.c	Wed Mar 21 17:03:00 2007 -0500
    98.2 +++ b/tools/ioemu/xenstore.c	Wed Mar 21 18:08:31 2007 -0500
    98.3 @@ -11,9 +11,14 @@
    98.4  #include "vl.h"
    98.5  #include "block_int.h"
    98.6  #include <unistd.h>
    98.7 +#include <sys/ipc.h>
    98.8 +#include <sys/shm.h>
    98.9 +#include <sys/types.h>
   98.10 +#include <sys/stat.h>
   98.11 +#include <fcntl.h>
   98.12  
   98.13  static struct xs_handle *xsh = NULL;
   98.14 -static char *hd_filename[MAX_DISKS];
   98.15 +static char *media_filename[MAX_DISKS];
   98.16  static QEMUTimer *insert_timer = NULL;
   98.17  
   98.18  #define UWAIT_MAX (30*1000000) /* thirty seconds */
   98.19 @@ -40,10 +45,10 @@ static void insert_media(void *opaque)
   98.20      int i;
   98.21  
   98.22      for (i = 0; i < MAX_DISKS; i++) {
   98.23 -	if (hd_filename[i]) {
   98.24 -	    do_change(bs_table[i]->device_name, hd_filename[i]);
   98.25 -	    free(hd_filename[i]);
   98.26 -	    hd_filename[i] = NULL;
   98.27 +	if (media_filename[i] && bs_table[i]) {
   98.28 +	    do_change(bs_table[i]->device_name, media_filename[i]);
   98.29 +	    free(media_filename[i]);
   98.30 +	    media_filename[i] = NULL;
   98.31  	}
   98.32      }
   98.33  }
   98.34 @@ -82,7 +87,7 @@ void xenstore_parse_domain_config(int do
   98.35      unsigned int len, num, hd_index;
   98.36  
   98.37      for(i = 0; i < MAX_DISKS; i++)
   98.38 -        hd_filename[i] = NULL;
   98.39 +        media_filename[i] = NULL;
   98.40  
   98.41      xsh = xs_daemon_open();
   98.42      if (xsh == NULL) {
   98.43 @@ -128,19 +133,12 @@ void xenstore_parse_domain_config(int do
   98.44  	    continue;
   98.45  	free(type);
   98.46  	type = xs_read(xsh, XBT_NULL, buf, &len);
   98.47 -	/* read params to get the patch of the image -- read it last
   98.48 -	 * so that we have its path in buf when setting up the
   98.49 -	 * watch */
   98.50  	if (pasprintf(&buf, "%s/params", bpath) == -1)
   98.51  	    continue;
   98.52  	free(params);
   98.53  	params = xs_read(xsh, XBT_NULL, buf, &len);
   98.54  	if (params == NULL)
   98.55  	    continue;
   98.56 -	if (params[0]) {
   98.57 -	    hd_filename[hd_index] = params;	/* strdup() */
   98.58 -	    params = NULL;		/* don't free params on re-use */
   98.59 -	}
   98.60          /* 
   98.61           * check if device has a phantom vbd; the phantom is hooked
   98.62           * to the frontend device (for ease of cleanup), so lookup 
   98.63 @@ -151,38 +149,42 @@ void xenstore_parse_domain_config(int do
   98.64  	    continue;
   98.65  	free(fpath);
   98.66          fpath = xs_read(xsh, XBT_NULL, buf, &len);
   98.67 -	if (fpath != NULL) {
   98.68 +	if (fpath) {
   98.69  	    if (pasprintf(&buf, "%s/dev", fpath) == -1)
   98.70  	        continue;
   98.71 +	    free(params);
   98.72              params = xs_read(xsh, XBT_NULL, buf , &len);
   98.73 -	    if (params != NULL) {
   98.74 -                free(hd_filename[hd_index]);
   98.75 -                hd_filename[hd_index] = params;
   98.76 -                params = NULL;              /* don't free params on re-use */
   98.77 +	    if (params) {
   98.78                  /* 
   98.79                   * wait for device, on timeout silently fail because we will 
   98.80                   * fail to open below
   98.81                   */
   98.82 -                waitForDevice(hd_filename[hd_index]);
   98.83 +                waitForDevice(params);
   98.84              }
   98.85          }
   98.86 +
   98.87  	bs_table[hd_index] = bdrv_new(dev);
   98.88 -        /* re-establish buf */
   98.89 -	if (pasprintf(&buf, "%s/params", bpath) == -1)
   98.90 -	    continue;
   98.91  	/* check if it is a cdrom */
   98.92  	if (type && !strcmp(type, "cdrom")) {
   98.93  	    bdrv_set_type_hint(bs_table[hd_index], BDRV_TYPE_CDROM);
   98.94 -	    xs_watch(xsh, buf, dev);
   98.95 +	    if (pasprintf(&buf, "%s/params", bpath) != -1)
   98.96 +		xs_watch(xsh, buf, dev);
   98.97  	}
   98.98 -	if (hd_filename[hd_index]) {
   98.99 -            if (bdrv_open(bs_table[hd_index], hd_filename[hd_index],
  98.100 -			  0 /* snapshot */) < 0)
  98.101 +	/* open device now if media present */
  98.102 +	if (params[0]) {
  98.103 +            if (bdrv_open(bs_table[hd_index], params, 0 /* snapshot */) < 0)
  98.104                  fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
  98.105 -                        hd_filename[hd_index]);
  98.106 +                        params);
  98.107  	}
  98.108      }
  98.109  
  98.110 +    /* Set a watch for log-dirty requests from the migration tools */
  98.111 +    if (pasprintf(&buf, "%s/logdirty/next-active", path) != -1) {
  98.112 +        xs_watch(xsh, buf, "logdirty");
  98.113 +        fprintf(logfile, "Watching %s\n", buf);
  98.114 +    }
  98.115 +
  98.116 +
  98.117   out:
  98.118      free(type);
  98.119      free(params);
  98.120 @@ -201,6 +203,116 @@ int xenstore_fd(void)
  98.121      return -1;
  98.122  }
  98.123  
  98.124 +unsigned long *logdirty_bitmap = NULL;
  98.125 +unsigned long logdirty_bitmap_size;
  98.126 +extern int vga_ram_size, bios_size;
  98.127 +
  98.128 +void xenstore_process_logdirty_event(void)
  98.129 +{
  98.130 +    char *act;
  98.131 +    static char *active_path = NULL;
  98.132 +    static char *next_active_path = NULL;
  98.133 +    static char *seg = NULL;
  98.134 +    unsigned int len;
  98.135 +    int i;
  98.136 +
  98.137 +    fprintf(logfile, "Triggered log-dirty buffer switch\n");
  98.138 +
  98.139 +    if (!seg) {
  98.140 +        char *path, *p, *key_ascii, key_terminated[17] = {0,};
  98.141 +        key_t key;
  98.142 +        int shmid;
  98.143 +
  98.144 +        /* Find and map the shared memory segment for log-dirty bitmaps */
  98.145 +        if (!(path = xs_get_domain_path(xsh, domid))) {            
  98.146 +            fprintf(logfile, "Log-dirty: can't get domain path in store\n");
  98.147 +            exit(1);
  98.148 +        }
  98.149 +        if (!(path = realloc(path, strlen(path) 
  98.150 +                             + strlen("/logdirty/next-active") + 1))) {
  98.151 +            fprintf(logfile, "Log-dirty: out of memory\n");
  98.152 +            exit(1);
  98.153 +        }
  98.154 +        strcat(path, "/logdirty/");
  98.155 +        p = path + strlen(path);
  98.156 +        strcpy(p, "key");
  98.157 +        
  98.158 +        key_ascii = xs_read(xsh, XBT_NULL, path, &len);
  98.159 +        if (!key_ascii) {
  98.160 +            /* No key yet: wait for the next watch */
  98.161 +            free(path);
  98.162 +            return;
  98.163 +        }
  98.164 +        strncpy(key_terminated, key_ascii, 16);
  98.165 +        free(key_ascii);
  98.166 +        key = (key_t) strtoull(key_terminated, NULL, 16);
  98.167 +
  98.168 +        /* Figure out how bit the log-dirty bitmaps are */
  98.169 +        logdirty_bitmap_size = ((phys_ram_size + 0x20 
  98.170 +                                 - (vga_ram_size + bios_size)) 
  98.171 +                                >> (TARGET_PAGE_BITS)); /* nr of bits in map*/
  98.172 +        if (logdirty_bitmap_size > HVM_BELOW_4G_MMIO_START >> TARGET_PAGE_BITS)
  98.173 +            logdirty_bitmap_size += 
  98.174 +                HVM_BELOW_4G_MMIO_LENGTH >> TARGET_PAGE_BITS; /* still bits */
  98.175 +        logdirty_bitmap_size = ((logdirty_bitmap_size + HOST_LONG_BITS - 1)
  98.176 +                                / HOST_LONG_BITS); /* longs */
  98.177 +        logdirty_bitmap_size *= sizeof (unsigned long); /* bytes */
  98.178 +
  98.179 +        /* Map the shared-memory segment */
  98.180 +        if ((shmid = shmget(key, 
  98.181 +                            2 * logdirty_bitmap_size, 
  98.182 +                            S_IRUSR|S_IWUSR)) == -1 
  98.183 +            || (seg = shmat(shmid, NULL, 0)) == (void *)-1) {
  98.184 +            fprintf(logfile, "Log-dirty: can't map segment %16.16llx (%s)\n",
  98.185 +                    (unsigned long long) key, strerror(errno));
  98.186 +            exit(1);
  98.187 +        }
  98.188 +
  98.189 +        fprintf(logfile, "Log-dirty: mapped segment at %p\n", seg);
  98.190 +
  98.191 +        /* Double-check that the bitmaps are the size we expect */
  98.192 +        if (logdirty_bitmap_size != *(uint32_t *)seg) {
  98.193 +            fprintf(logfile, "Log-dirty: got %lu, calc %lu\n", 
  98.194 +                    *(uint32_t *)seg, logdirty_bitmap_size);
  98.195 +            return;
  98.196 +        }
  98.197 +
  98.198 +        /* Remember the paths for the next-active and active entries */
  98.199 +        strcpy(p, "active");
  98.200 +        if (!(active_path = strdup(path))) {
  98.201 +            fprintf(logfile, "Log-dirty: out of memory\n");
  98.202 +            exit(1);
  98.203 +        }
  98.204 +        strcpy(p, "next-active");
  98.205 +        if (!(next_active_path = strdup(path))) {
  98.206 +            fprintf(logfile, "Log-dirty: out of memory\n");
  98.207 +            exit(1);
  98.208 +        }
  98.209 +        free(path);
  98.210 +    }
  98.211 +    
  98.212 +    /* Read the required active buffer from the store */
  98.213 +    act = xs_read(xsh, XBT_NULL, next_active_path, &len);
  98.214 +    if (!act) {
  98.215 +        fprintf(logfile, "Log-dirty: can't read next-active\n");
  98.216 +        exit(1);
  98.217 +    }
  98.218 +
  98.219 +    /* Switch buffers */
  98.220 +    i = act[0] - '0';
  98.221 +    if (i != 0 && i != 1) {
  98.222 +        fprintf(logfile, "Log-dirty: bad next-active entry: %s\n", act);
  98.223 +        exit(1);
  98.224 +    }
  98.225 +    logdirty_bitmap = seg + i * logdirty_bitmap_size;
  98.226 +
  98.227 +    /* Ack that we've switched */
  98.228 +    xs_write(xsh, XBT_NULL, active_path, act, len);
  98.229 +    free(act);
  98.230 +}
  98.231 +
  98.232 +
  98.233 +
  98.234  void xenstore_process_event(void *opaque)
  98.235  {
  98.236      char **vec, *image = NULL;
  98.237 @@ -210,6 +322,11 @@ void xenstore_process_event(void *opaque
  98.238      if (!vec)
  98.239  	return;
  98.240  
  98.241 +    if (!strcmp(vec[XS_WATCH_TOKEN], "logdirty")) {
  98.242 +        xenstore_process_logdirty_event();
  98.243 +        goto out;
  98.244 +    }
  98.245 +
  98.246      if (strncmp(vec[XS_WATCH_TOKEN], "hd", 2) ||
  98.247  	strlen(vec[XS_WATCH_TOKEN]) != 3)
  98.248  	goto out;
  98.249 @@ -220,13 +337,13 @@ void xenstore_process_event(void *opaque
  98.250  
  98.251      do_eject(0, vec[XS_WATCH_TOKEN]);
  98.252      bs_table[hd_index]->filename[0] = 0;
  98.253 -    if (hd_filename[hd_index]) {
  98.254 -	free(hd_filename[hd_index]);
  98.255 -	hd_filename[hd_index] = NULL;
  98.256 +    if (media_filename[hd_index]) {
  98.257 +	free(media_filename[hd_index]);
  98.258 +	media_filename[hd_index] = NULL;
  98.259      }
  98.260  
  98.261      if (image[0]) {
  98.262 -	hd_filename[hd_index] = strdup(image);
  98.263 +	media_filename[hd_index] = strdup(image);
  98.264  	xenstore_check_new_media_present(5000);
  98.265      }
  98.266  
    99.1 --- a/tools/libxc/Makefile	Wed Mar 21 17:03:00 2007 -0500
    99.2 +++ b/tools/libxc/Makefile	Wed Mar 21 18:08:31 2007 -0500
    99.3 @@ -58,7 +58,7 @@ GUEST_SRCS-$(CONFIG_POWERPC) += xc_dom_p
    99.4  
    99.5  CFLAGS   += -Werror -Wmissing-prototypes
    99.6  CFLAGS   += -fno-strict-aliasing
    99.7 -CFLAGS   += $(INCLUDES) -I.
    99.8 +CFLAGS   += $(INCLUDES) -I. -I../xenstore
    99.9  
   99.10  # Needed for posix_fadvise64() in xc_linux.c
   99.11  CFLAGS-$(CONFIG_Linux) += -D_GNU_SOURCE
   100.1 --- a/tools/libxc/xc_core.c	Wed Mar 21 17:03:00 2007 -0500
   100.2 +++ b/tools/libxc/xc_core.c	Wed Mar 21 18:08:31 2007 -0500
   100.3 @@ -349,11 +349,7 @@ xc_domain_dumpcore_via_callback(int xc_h
   100.4      /* Map the shared info frame */
   100.5      live_shinfo = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
   100.6                                         PROT_READ, info.shared_info_frame);
   100.7 -    if ( !live_shinfo 
   100.8 -#ifdef __ia64__
   100.9 -         && !info.hvm
  100.10 -#endif
  100.11 -        )
  100.12 +    if ( !live_shinfo && !info.hvm )
  100.13      {
  100.14          PERROR("Couldn't map live_shinfo");
  100.15          goto out;
   101.1 --- a/tools/libxc/xc_core_ia64.c	Wed Mar 21 17:03:00 2007 -0500
   101.2 +++ b/tools/libxc/xc_core_ia64.c	Wed Mar 21 18:08:31 2007 -0500
   101.3 @@ -22,6 +22,28 @@
   101.4  #include "xc_core.h"
   101.5  #include "xc_efi.h"
   101.6  #include "xc_dom.h"
   101.7 +#include <inttypes.h>
   101.8 +
   101.9 +static int
  101.10 +xc_memory_map_cmp(const void *lhs__, const void *rhs__)
  101.11 +{
  101.12 +    const struct xc_core_memory_map *lhs =
  101.13 +        (const struct xc_core_memory_map *)lhs__;
  101.14 +    const struct xc_core_memory_map *rhs =
  101.15 +        (const struct xc_core_memory_map *)rhs__;
  101.16 +
  101.17 +    if (lhs->addr < rhs->addr)
  101.18 +        return -1;
  101.19 +    if (lhs->addr > rhs->addr)
  101.20 +        return 1;
  101.21 +
  101.22 +    /* memory map overlap isn't allowed. complain */
  101.23 +    DPRINTF("duplicated addresses are detected "
  101.24 +            "(0x%" PRIx64 ", 0x%" PRIx64 "), "
  101.25 +            "(0x%" PRIx64 ", 0x%" PRIx64 ")\n",
  101.26 +            lhs->addr, lhs->size, rhs->addr, rhs->size);
  101.27 +    return 0;
  101.28 +}
  101.29  
  101.30  int
  101.31  xc_core_arch_auto_translated_physmap(const xc_dominfo_t *info)
  101.32 @@ -111,6 +133,7 @@ memory_map_get_old_hvm(int xc_handle, xc
  101.33      }
  101.34      *mapp = map;
  101.35      *nr_entries = i;
  101.36 +    qsort(map, *nr_entries, sizeof(map[0]), &xc_memory_map_cmp);
  101.37      return 0;
  101.38  
  101.39  out:
  101.40 @@ -196,6 +219,7 @@ xc_core_arch_memory_map_get(int xc_handl
  101.41      ret = 0;
  101.42  out:
  101.43      munmap(memmap_info, PAGE_SIZE);
  101.44 +    qsort(map, *nr_entries, sizeof(map[0]), &xc_memory_map_cmp);
  101.45      return ret;
  101.46      
  101.47  old:
   102.1 --- a/tools/libxc/xc_core_x86.c	Wed Mar 21 17:03:00 2007 -0500
   102.2 +++ b/tools/libxc/xc_core_x86.c	Wed Mar 21 18:08:31 2007 -0500
   102.3 @@ -21,12 +21,15 @@
   102.4  #include "xg_private.h"
   102.5  #include "xc_core.h"
   102.6  
   102.7 +static int max_gpfn(int xc_handle, domid_t domid)
   102.8 +{
   102.9 +    return xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &domid);
  102.10 +}
  102.11 +
  102.12  int
  102.13  xc_core_arch_auto_translated_physmap(const xc_dominfo_t *info)
  102.14  {
  102.15 -    if ( info->hvm )
  102.16 -        return 1;
  102.17 -    return 0;
  102.18 +    return info->hvm;
  102.19  }
  102.20  
  102.21  int
  102.22 @@ -35,14 +38,14 @@ xc_core_arch_memory_map_get(int xc_handl
  102.23                              xc_core_memory_map_t **mapp,
  102.24                              unsigned int *nr_entries)
  102.25  {
  102.26 -    unsigned long max_pfn = live_shinfo->arch.max_pfn;
  102.27 -    xc_core_memory_map_t *map = NULL;
  102.28 +    unsigned long max_pfn = max_gpfn(xc_handle, info->domid);
  102.29 +    xc_core_memory_map_t *map;
  102.30  
  102.31      map = malloc(sizeof(*map));
  102.32 -    if ( !map )
  102.33 +    if ( map == NULL )
  102.34      {
  102.35          PERROR("Could not allocate memory");
  102.36 -        goto out;
  102.37 +        return -1;
  102.38      }
  102.39  
  102.40      map->addr = 0;
  102.41 @@ -51,11 +54,6 @@ xc_core_arch_memory_map_get(int xc_handl
  102.42      *mapp = map;
  102.43      *nr_entries = 1;
  102.44      return 0;
  102.45 -
  102.46 -out:
  102.47 -    if ( map )
  102.48 -        free(map);
  102.49 -    return -1;
  102.50  }
  102.51  
  102.52  int
  102.53 @@ -67,7 +65,7 @@ xc_core_arch_map_p2m(int xc_handle, xc_d
  102.54      xen_pfn_t *live_p2m_frame_list_list = NULL;
  102.55      xen_pfn_t *live_p2m_frame_list = NULL;
  102.56      uint32_t dom = info->domid;
  102.57 -    unsigned long max_pfn = live_shinfo->arch.max_pfn;
  102.58 +    unsigned long max_pfn = max_gpfn(xc_handle, info->domid);
  102.59      int ret = -1;
  102.60      int err;
  102.61  
   103.1 --- a/tools/libxc/xc_dom_x86.c	Wed Mar 21 17:03:00 2007 -0500
   103.2 +++ b/tools/libxc/xc_dom_x86.c	Wed Mar 21 18:08:31 2007 -0500
   103.3 @@ -434,24 +434,12 @@ static int vcpu_x86_32(struct xc_dom_ima
   103.4  {
   103.5      vcpu_guest_context_x86_32_t *ctxt = ptr;
   103.6      xen_pfn_t cr3_pfn;
   103.7 -    int i;
   103.8  
   103.9      xc_dom_printf("%s: called\n", __FUNCTION__);
  103.10  
  103.11      /* clear everything */
  103.12      memset(ctxt, 0, sizeof(*ctxt));
  103.13  
  103.14 -    /* Virtual IDT is empty at start-of-day. */
  103.15 -    for ( i = 0; i < 256; i++ )
  103.16 -    {
  103.17 -        ctxt->trap_ctxt[i].vector = i;
  103.18 -        ctxt->trap_ctxt[i].cs = FLAT_KERNEL_CS_X86_32;
  103.19 -    }
  103.20 -
  103.21 -    /* No callback handlers. */
  103.22 -    ctxt->event_callback_cs = FLAT_KERNEL_CS_X86_32;
  103.23 -    ctxt->failsafe_callback_cs = FLAT_KERNEL_CS_X86_32;
  103.24 -
  103.25      ctxt->user_regs.ds = FLAT_KERNEL_DS_X86_32;
  103.26      ctxt->user_regs.es = FLAT_KERNEL_DS_X86_32;
  103.27      ctxt->user_regs.fs = FLAT_KERNEL_DS_X86_32;
  103.28 @@ -465,11 +453,10 @@ static int vcpu_x86_32(struct xc_dom_ima
  103.29          dom->parms.virt_base + (dom->start_info_pfn) * PAGE_SIZE_X86;
  103.30      ctxt->user_regs.eflags = 1 << 9; /* Interrupt Enable */
  103.31  
  103.32 -    ctxt->kernel_ss = FLAT_KERNEL_SS_X86_32;
  103.33 -    ctxt->kernel_sp =
  103.34 -        dom->parms.virt_base + (dom->bootstack_pfn + 1) * PAGE_SIZE_X86;
  103.35 +    ctxt->kernel_ss = ctxt->user_regs.ss;
  103.36 +    ctxt->kernel_sp = ctxt->user_regs.esp;
  103.37  
  103.38 -    ctxt->flags = VGCF_in_kernel_X86_32;
  103.39 +    ctxt->flags = VGCF_in_kernel_X86_32 | VGCF_online_X86_32;
  103.40      if ( dom->parms.pae == 2 /* extended_cr3 */ ||
  103.41           dom->parms.pae == 3 /* bimodal */ )
  103.42          ctxt->vm_assist |= (1UL << VMASST_TYPE_pae_extended_cr3);
  103.43 @@ -486,20 +473,12 @@ static int vcpu_x86_64(struct xc_dom_ima
  103.44  {
  103.45      vcpu_guest_context_x86_64_t *ctxt = ptr;
  103.46      xen_pfn_t cr3_pfn;
  103.47 -    int i;
  103.48  
  103.49      xc_dom_printf("%s: called\n", __FUNCTION__);
  103.50  
  103.51      /* clear everything */
  103.52      memset(ctxt, 0, sizeof(*ctxt));
  103.53  
  103.54 -    /* Virtual IDT is empty at start-of-day. */
  103.55 -    for ( i = 0; i < 256; i++ )
  103.56 -    {
  103.57 -        ctxt->trap_ctxt[i].vector = i;
  103.58 -        ctxt->trap_ctxt[i].cs = FLAT_KERNEL_CS_X86_64;
  103.59 -    }
  103.60 -
  103.61      ctxt->user_regs.ds = FLAT_KERNEL_DS_X86_64;
  103.62      ctxt->user_regs.es = FLAT_KERNEL_DS_X86_64;
  103.63      ctxt->user_regs.fs = FLAT_KERNEL_DS_X86_64;
  103.64 @@ -513,11 +492,10 @@ static int vcpu_x86_64(struct xc_dom_ima
  103.65          dom->parms.virt_base + (dom->start_info_pfn) * PAGE_SIZE_X86;
  103.66      ctxt->user_regs.rflags = 1 << 9; /* Interrupt Enable */
  103.67  
  103.68 -    ctxt->kernel_ss = FLAT_KERNEL_SS_X86_64;
  103.69 -    ctxt->kernel_sp =
  103.70 -        dom->parms.virt_base + (dom->bootstack_pfn + 1) * PAGE_SIZE_X86;
  103.71 +    ctxt->kernel_ss = ctxt->user_regs.ss;
  103.72 +    ctxt->kernel_sp = ctxt->user_regs.esp;
  103.73  
  103.74 -    ctxt->flags = VGCF_in_kernel_X86_64;
  103.75 +    ctxt->flags = VGCF_in_kernel_X86_64 | VGCF_online_X86_64;
  103.76      cr3_pfn = xc_dom_p2m_guest(dom, dom->pgtables_seg.pfn);
  103.77      ctxt->ctrlreg[3] = xen_pfn_to_cr3_x86_64(cr3_pfn);
  103.78      xc_dom_printf("%s: cr3: pfn 0x%" PRIpfn " mfn 0x%" PRIpfn "\n",
   104.1 --- a/tools/libxc/xc_hvm_build.c	Wed Mar 21 17:03:00 2007 -0500
   104.2 +++ b/tools/libxc/xc_hvm_build.c	Wed Mar 21 18:08:31 2007 -0500
   104.3 @@ -137,6 +137,12 @@ static void build_e820map(void *e820_pag
   104.4      e820entry[nr_map].type = E820_RAM;
   104.5      nr_map++;
   104.6  
   104.7 +    /* Explicitly reserve space for special pages (ioreq and xenstore). */
   104.8 +    e820entry[nr_map].addr = mem_size - PAGE_SIZE * 3;
   104.9 +    e820entry[nr_map].size = PAGE_SIZE * 3;
  104.10 +    e820entry[nr_map].type = E820_RESERVED;
  104.11 +    nr_map++;
  104.12 +
  104.13      if ( extra_mem_size )
  104.14      {
  104.15          e820entry[nr_map].addr = (1ULL << 32);
  104.16 @@ -280,7 +286,6 @@ static int setup_guest(int xc_handle,
  104.17      /* NB. evtchn_upcall_mask is unused: leave as zero. */
  104.18      memset(&shared_info->evtchn_mask[0], 0xff,
  104.19             sizeof(shared_info->evtchn_mask));
  104.20 -    shared_info->arch.max_pfn = page_array[nr_pages - 1];
  104.21      munmap(shared_info, PAGE_SIZE);
  104.22  
  104.23      if ( v_end > HVM_BELOW_4G_RAM_END )
  104.24 @@ -302,9 +307,15 @@ static int setup_guest(int xc_handle,
  104.25  
  104.26      /* Set [er]ip in the way that's right for Xen */
  104.27      if ( strstr(caps, "x86_64") )
  104.28 +    {
  104.29          ctxt->c64.user_regs.rip = elf_uval(&elf, elf.ehdr, e_entry); 
  104.30 +        ctxt->c64.flags = VGCF_online;
  104.31 +    }
  104.32      else
  104.33 +    {
  104.34          ctxt->c32.user_regs.eip = elf_uval(&elf, elf.ehdr, e_entry);
  104.35 +        ctxt->c32.flags = VGCF_online;
  104.36 +    }
  104.37  
  104.38      return 0;
  104.39  
  104.40 @@ -344,7 +355,7 @@ static int xc_hvm_build_internal(int xc_
  104.41  
  104.42      memset(&launch_domctl, 0, sizeof(launch_domctl));
  104.43      launch_domctl.domain = (domid_t)domid;
  104.44 -    launch_domctl.u.vcpucontext.vcpu   = 0;
  104.45 +    launch_domctl.u.vcpucontext.vcpu = 0;
  104.46      set_xen_guest_handle(launch_domctl.u.vcpucontext.ctxt, &ctxt.c);
  104.47      launch_domctl.cmd = XEN_DOMCTL_setvcpucontext;
  104.48      rc = xc_domctl(xc_handle, &launch_domctl);
   105.1 --- a/tools/libxc/xc_hvm_restore.c	Wed Mar 21 17:03:00 2007 -0500
   105.2 +++ b/tools/libxc/xc_hvm_restore.c	Wed Mar 21 18:08:31 2007 -0500
   105.3 @@ -70,9 +70,6 @@ int xc_hvm_restore(int xc_handle, int io
   105.4  {
   105.5      DECLARE_DOMCTL;
   105.6  
   105.7 -    /* The new domain's shared-info frame number. */
   105.8 -    unsigned long shared_info_frame;
   105.9 -
  105.10      /* A copy of the CPU context of the guest. */
  105.11      vcpu_guest_context_t ctxt;
  105.12  
  105.13 @@ -86,8 +83,6 @@ int xc_hvm_restore(int xc_handle, int io
  105.14      uint8_t *hvm_buf = NULL;
  105.15      unsigned long long v_end, memsize;
  105.16      unsigned long shared_page_nr;
  105.17 -    shared_info_t *shared_info = NULL;
  105.18 -    xen_pfn_t arch_max_pfn;
  105.19  
  105.20      unsigned long pfn;
  105.21      unsigned int prev_pc, this_pc;
  105.22 @@ -96,11 +91,12 @@ int xc_hvm_restore(int xc_handle, int io
  105.23      /* Types of the pfns in the current region */
  105.24      unsigned long region_pfn_type[MAX_BATCH_SIZE];
  105.25  
  105.26 -    struct xen_add_to_physmap xatp;
  105.27 -
  105.28      /* Number of pages of memory the guest has.  *Not* the same as max_pfn. */
  105.29      unsigned long nr_pages;
  105.30  
  105.31 +    /* The size of an array big enough to contain all guest pfns */
  105.32 +    unsigned long pfn_array_size = max_pfn + 1;
  105.33 +
  105.34      /* hvm guest mem size (Mb) */
  105.35      memsize = (unsigned long long)*store_mfn;
  105.36      v_end = memsize << 20;
  105.37 @@ -127,7 +123,7 @@ int xc_hvm_restore(int xc_handle, int io
  105.38      }
  105.39  
  105.40  
  105.41 -    pfns = malloc(max_pfn * sizeof(xen_pfn_t));
  105.42 +    pfns = malloc(pfn_array_size * sizeof(xen_pfn_t));
  105.43      if (pfns == NULL) {
  105.44          ERROR("memory alloc failed");
  105.45          errno = ENOMEM;
  105.46 @@ -139,11 +135,10 @@ int xc_hvm_restore(int xc_handle, int io
  105.47          goto out;
  105.48      }
  105.49  
  105.50 -    for ( i = 0; i < max_pfn; i++ )
  105.51 +    for ( i = 0; i < pfn_array_size; i++ )
  105.52          pfns[i] = i;
  105.53 -    for ( i = HVM_BELOW_4G_RAM_END >> PAGE_SHIFT; i < max_pfn; i++ )
  105.54 +    for ( i = HVM_BELOW_4G_RAM_END >> PAGE_SHIFT; i < pfn_array_size; i++ )
  105.55          pfns[i] += HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT;
  105.56 -    arch_max_pfn = pfns[max_pfn - 1];/* used later */
  105.57  
  105.58      /* Allocate memory for HVM guest, skipping VGA hole 0xA0000-0xC0000. */
  105.59      rc = xc_domain_memory_populate_physmap(
  105.60 @@ -281,6 +276,14 @@ int xc_hvm_restore(int xc_handle, int io
  105.61      else
  105.62          shared_page_nr = (v_end >> PAGE_SHIFT) - 1;
  105.63  
  105.64 +    /* Paranoia: clean pages. */
  105.65 +    if ( xc_clear_domain_page(xc_handle, dom, shared_page_nr) ||
  105.66 +         xc_clear_domain_page(xc_handle, dom, shared_page_nr-1) ||
  105.67 +         xc_clear_domain_page(xc_handle, dom, shared_page_nr-2) ) {
  105.68 +        ERROR("error clearing comms frames!\n");
  105.69 +        goto out;
  105.70 +    }
  105.71 +
  105.72      xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_PFN, shared_page_nr-1);
  105.73      xc_set_hvm_param(xc_handle, dom, HVM_PARAM_BUFIOREQ_PFN, shared_page_nr-2);
  105.74      xc_set_hvm_param(xc_handle, dom, HVM_PARAM_IOREQ_PFN, shared_page_nr);
  105.75 @@ -289,29 +292,6 @@ int xc_hvm_restore(int xc_handle, int io
  105.76      *store_mfn = (v_end >> PAGE_SHIFT) - 2;
  105.77      DPRINTF("hvm restore:calculate new store_mfn=0x%lx,v_end=0x%llx..\n", *store_mfn, v_end);
  105.78  
  105.79 -    /* restore hvm context including pic/pit/shpage */
  105.80 -    if (!read_exact(io_fd, &rec_len, sizeof(uint32_t))) {
  105.81 -        ERROR("error read hvm context size!\n");
  105.82 -        goto out;
  105.83 -    }
  105.84 -
  105.85 -    hvm_buf = malloc(rec_len);
  105.86 -    if (hvm_buf == NULL) {
  105.87 -        ERROR("memory alloc for hvm context buffer failed");
  105.88 -        errno = ENOMEM;
  105.89 -        goto out;
  105.90 -    }
  105.91 -
  105.92 -    if (!read_exact(io_fd, hvm_buf, rec_len)) {
  105.93 -        ERROR("error read hvm buffer!\n");
  105.94 -        goto out;
  105.95 -    }
  105.96 -
  105.97 -    if (( rc = xc_domain_hvm_setcontext(xc_handle, dom, hvm_buf, rec_len))) {
  105.98 -        ERROR("error set hvm buffer!\n");
  105.99 -        goto out;
 105.100 -    }
 105.101 -
 105.102      if (!read_exact(io_fd, &nr_vcpus, sizeof(uint32_t))) {
 105.103          ERROR("error read nr vcpu !\n");
 105.104          goto out;
 105.105 @@ -339,28 +319,28 @@ int xc_hvm_restore(int xc_handle, int io
 105.106          }
 105.107      }
 105.108  
 105.109 -    /* Shared-info pfn */
 105.110 -    if (!read_exact(io_fd, &(shared_info_frame), sizeof(uint32_t)) ) {
 105.111 -        ERROR("reading the shared-info pfn failed!\n");
 105.112 +    /* restore hvm context including pic/pit/shpage */
 105.113 +    if (!read_exact(io_fd, &rec_len, sizeof(uint32_t))) {
 105.114 +        ERROR("error read hvm context size!\n");
 105.115          goto out;
 105.116      }
 105.117 -    /* Map the shared-info frame where it was before */
 105.118 -    xatp.domid = dom;
 105.119 -    xatp.space = XENMAPSPACE_shared_info;
 105.120 -    xatp.idx   = 0;
 105.121 -    xatp.gpfn  = shared_info_frame;
 105.122 -    if ( (rc = xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp)) != 0 ) {
 105.123 -        ERROR("setting the shared-info pfn failed!\n");
 105.124 +
 105.125 +    hvm_buf = malloc(rec_len);
 105.126 +    if (hvm_buf == NULL) {
 105.127 +        ERROR("memory alloc for hvm context buffer failed");
 105.128 +        errno = ENOMEM;
 105.129          goto out;
 105.130      }
 105.131 -    if ( (xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp) != 0) ||
 105.132 -         ((shared_info = xc_map_foreign_range(
 105.133 -             xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
 105.134 -             shared_info_frame)) == NULL) )
 105.135 +
 105.136 +    if (!read_exact(io_fd, hvm_buf, rec_len)) {
 105.137 +        ERROR("error read hvm buffer!\n");
 105.138          goto out;
 105.139 -    /* shared_info.arch.max_pfn is used by dump-core */
 105.140 -    shared_info->arch.max_pfn = arch_max_pfn;
 105.141 -    munmap(shared_info, PAGE_SIZE);
 105.142 +    }
 105.143 +
 105.144 +    if (( rc = xc_domain_hvm_setcontext(xc_handle, dom, hvm_buf, rec_len))) {
 105.145 +        ERROR("error set hvm buffer!\n");
 105.146 +        goto out;
 105.147 +    }
 105.148  
 105.149      rc = 0;
 105.150      goto out;
   106.1 --- a/tools/libxc/xc_hvm_save.c	Wed Mar 21 17:03:00 2007 -0500
   106.2 +++ b/tools/libxc/xc_hvm_save.c	Wed Mar 21 18:08:31 2007 -0500
   106.3 @@ -27,12 +27,14 @@
   106.4  #include <stdlib.h>
   106.5  #include <unistd.h>
   106.6  #include <sys/time.h>
   106.7 -#include <xen/hvm/e820.h>
   106.8  
   106.9  #include "xc_private.h"
  106.10  #include "xg_private.h"
  106.11  #include "xg_save_restore.h"
  106.12  
  106.13 +#include <xen/hvm/e820.h>
  106.14 +#include <xen/hvm/params.h>
  106.15 +
  106.16  /*
  106.17  ** Default values for important tuning parameters. Can override by passing
  106.18  ** non-zero replacement values to xc_hvm_save().
  106.19 @@ -49,11 +51,30 @@ static unsigned long max_mfn;
  106.20  /* virtual starting address of the hypervisor */
  106.21  static unsigned long hvirt_start;
  106.22  
  106.23 -/* #levels of page tables used by the currrent guest */
  106.24 +/* #levels of page tables used by the current guest */
  106.25  static unsigned int pt_levels;
  106.26  
  106.27 -/* total number of pages used by the current guest */
  106.28 -static unsigned long max_pfn;
  106.29 +/* Shared-memory bitmaps for getting log-dirty bits from qemu */
  106.30 +static unsigned long *qemu_bitmaps[2];
  106.31 +static int qemu_active;
  106.32 +static int qemu_non_active;
  106.33 +
  106.34 +int xc_hvm_drain_io(int handle, domid_t dom)
  106.35 +{
  106.36 +    DECLARE_HYPERCALL;
  106.37 +    xen_hvm_drain_io_t arg;
  106.38 +    int rc;
  106.39 +
  106.40 +    hypercall.op     = __HYPERVISOR_hvm_op;
  106.41 +    hypercall.arg[0] = HVMOP_drain_io;
  106.42 +    hypercall.arg[1] = (unsigned long)&arg;
  106.43 +    arg.domid = dom;
  106.44 +    if ( lock_pages(&arg, sizeof(arg)) != 0 )
  106.45 +        return -1;
  106.46 +    rc = do_xen_hypercall(handle, &hypercall);
  106.47 +    unlock_pages(&arg, sizeof(arg));
  106.48 +    return rc;
  106.49 +}
  106.50  
  106.51  /*
  106.52  ** During (live) save/migrate, we maintain a number of bitmaps to track
  106.53 @@ -61,7 +82,8 @@ static unsigned long max_pfn;
  106.54  */
  106.55  
  106.56  #define BITS_PER_LONG (sizeof(unsigned long) * 8)
  106.57 -#define BITMAP_SIZE   ((max_pfn + BITS_PER_LONG - 1) / 8)
  106.58 +#define BITS_TO_LONGS(bits) (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
  106.59 +#define BITMAP_SIZE   (BITS_TO_LONGS(pfn_array_size) * sizeof(unsigned long))
  106.60  
  106.61  #define BITMAP_ENTRY(_nr,_bmap) \
  106.62     ((unsigned long *)(_bmap))[(_nr)/BITS_PER_LONG]
  106.63 @@ -108,6 +130,7 @@ static inline int permute( int i, int nr
  106.64      return i;
  106.65  }
  106.66  
  106.67 +
  106.68  static uint64_t tv_to_us(struct timeval *new)
  106.69  {
  106.70      return (new->tv_sec * 1000000) + new->tv_usec;
  106.71 @@ -183,7 +206,7 @@ static int print_stats(int xc_handle, ui
  106.72      return 0;
  106.73  }
  106.74  
  106.75 -static int analysis_phase(int xc_handle, uint32_t domid, int max_pfn,
  106.76 +static int analysis_phase(int xc_handle, uint32_t domid, int pfn_array_size,
  106.77                            unsigned long *arr, int runs)
  106.78  {
  106.79      long long start, now;
  106.80 @@ -196,7 +219,7 @@ static int analysis_phase(int xc_handle,
  106.81          int i;
  106.82  
  106.83          xc_shadow_control(xc_handle, domid, XEN_DOMCTL_SHADOW_OP_CLEAN,
  106.84 -                          arr, max_pfn, NULL, 0, NULL);
  106.85 +                          arr, pfn_array_size, NULL, 0, NULL);
  106.86          DPRINTF("#Flush\n");
  106.87          for ( i = 0; i < 40; i++ ) {
  106.88              usleep(50000);
  106.89 @@ -236,7 +259,7 @@ static int suspend_and_state(int (*suspe
  106.90  
  106.91  
  106.92      if (info->shutdown && info->shutdown_reason == SHUTDOWN_suspend)
  106.93 -        return 0; // success
  106.94 +        return 0; // success        
  106.95  
  106.96      if (info->paused) {
  106.97          // try unpausing domain, wait, and retest
  106.98 @@ -261,17 +284,26 @@ static int suspend_and_state(int (*suspe
  106.99  }
 106.100  
 106.101  int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
 106.102 -                  uint32_t max_factor, uint32_t flags, int (*suspend)(int))
 106.103 +                uint32_t max_factor, uint32_t flags, int (*suspend)(int),
 106.104 +                void *(*init_qemu_maps)(int, unsigned), 
 106.105 +                void (*qemu_flip_buffer)(int, int))
 106.106  {
 106.107      xc_dominfo_t info;
 106.108  
 106.109      int rc = 1, i, j, last_iter, iter = 0;
 106.110      int live  = (flags & XCFLAGS_LIVE);
 106.111      int debug = (flags & XCFLAGS_DEBUG);
 106.112 +    int stdvga = (flags & XCFLAGS_STDVGA);
 106.113      int sent_last_iter, skip_this_iter;
 106.114  
 106.115 -    /* The new domain's shared-info frame number. */
 106.116 -    unsigned long shared_info_frame;
 106.117 +    /* The highest guest-physical frame number used by the current guest */
 106.118 +    unsigned long max_pfn;
 106.119 +
 106.120 +    /* The size of an array big enough to contain all guest pfns */
 106.121 +    unsigned long pfn_array_size;
 106.122 +
 106.123 +    /* Other magic frames: ioreqs and xenstore comms */
 106.124 +    unsigned long ioreq_pfn, bufioreq_pfn, store_pfn;
 106.125  
 106.126      /* A copy of the CPU context of the guest. */
 106.127      vcpu_guest_context_t ctxt;
 106.128 @@ -283,15 +315,12 @@ int xc_hvm_save(int xc_handle, int io_fd
 106.129      uint32_t hvm_buf_size;
 106.130      uint8_t *hvm_buf = NULL;
 106.131  
 106.132 -    /* Live mapping of shared info structure */
 106.133 -    shared_info_t *live_shinfo = NULL;
 106.134 -
 106.135      /* base of the region in which domain memory is mapped */
 106.136      unsigned char *region_base = NULL;
 106.137  
 106.138      uint32_t rec_size, nr_vcpus;
 106.139  
 106.140 -    /* power of 2 order of max_pfn */
 106.141 +    /* power of 2 order of pfn_array_size */
 106.142      int order_nr;
 106.143  
 106.144      /* bitmap of pages:
 106.145 @@ -337,7 +366,6 @@ int xc_hvm_save(int xc_handle, int io_fd
 106.146          ERROR("HVM:Could not get vcpu context");
 106.147          goto out;
 106.148      }
 106.149 -    shared_info_frame = info.shared_info_frame;
 106.150  
 106.151      /* cheesy sanity check */
 106.152      if ((info.max_memkb >> (PAGE_SHIFT - 10)) > max_mfn) {
 106.153 @@ -346,10 +374,12 @@ int xc_hvm_save(int xc_handle, int io_fd
 106.154          goto out;
 106.155      }
 106.156  
 106.157 -    /* Map the shared info frame */
 106.158 -    if(!(live_shinfo = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
 106.159 -                                            PROT_READ, shared_info_frame))) {
 106.160 -        ERROR("HVM:Couldn't map live_shinfo");
 106.161 +    if ( xc_get_hvm_param(xc_handle, dom, HVM_PARAM_STORE_PFN, &store_pfn)
 106.162 +         || xc_get_hvm_param(xc_handle, dom, HVM_PARAM_IOREQ_PFN, &ioreq_pfn)
 106.163 +         || xc_get_hvm_param(xc_handle, dom, 
 106.164 +                             HVM_PARAM_BUFIOREQ_PFN, &bufioreq_pfn) )
 106.165 +    {
 106.166 +        ERROR("HVM: Could not read magic PFN parameters");
 106.167          goto out;
 106.168      }
 106.169  
 106.170 @@ -357,8 +387,6 @@ int xc_hvm_save(int xc_handle, int io_fd
 106.171              "nr_pages=0x%lx\n", info.max_memkb, max_mfn, info.nr_pages); 
 106.172  
 106.173      if (live) {
 106.174 -        ERROR("hvm domain doesn't support live migration now.\n");
 106.175 -        goto out;
 106.176          
 106.177          if (xc_shadow_control(xc_handle, dom,
 106.178                                XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY,
 106.179 @@ -368,6 +396,7 @@ int xc_hvm_save(int xc_handle, int io_fd
 106.180          }
 106.181  
 106.182          last_iter = 0;
 106.183 +
 106.184          DPRINTF("hvm domain live migration debug start: logdirty enable.\n");
 106.185      } else {
 106.186          /* This is a non-live suspend. Issue the call back to get the
 106.187 @@ -388,20 +417,28 @@ int xc_hvm_save(int xc_handle, int io_fd
 106.188  
 106.189      /* Calculate the highest PFN of "normal" memory:
 106.190       * HVM memory is sequential except for the VGA and MMIO holes. */
 106.191 -    max_pfn = info.nr_pages;
 106.192 +    max_pfn = info.nr_pages - 1;
 106.193 +    /* If the domain has a Cirrus framebuffer and we haven't already 
 106.194 +     * suspended qemu-dm, it will have 8MB of framebuffer memory 
 106.195 +     * still allocated, which we don't want to copy: qemu will save it 
 106.196 +     * for us later */
 106.197 +    if ( live && !stdvga )
 106.198 +        max_pfn -= 0x800;
 106.199      /* Skip the VGA hole from 0xa0000 to 0xc0000 */
 106.200 -    max_pfn += 0x20;   
 106.201 +    max_pfn += 0x20;
 106.202      /* Skip the MMIO hole: 256MB just below 4GB */
 106.203      if ( max_pfn >= (HVM_BELOW_4G_MMIO_START >> PAGE_SHIFT) )
 106.204          max_pfn += (HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT); 
 106.205  
 106.206 -    skip_this_iter = 0;/*XXX*/
 106.207 -    /* pretend we sent all the pages last iteration */
 106.208 -    sent_last_iter = max_pfn;
 106.209 +    /* Size of any array that covers 0 ... max_pfn */
 106.210 +    pfn_array_size = max_pfn + 1;
 106.211  
 106.212 -    /* calculate the power of 2 order of max_pfn, e.g.
 106.213 +    /* pretend we sent all the pages last iteration */
 106.214 +    sent_last_iter = pfn_array_size;
 106.215 +
 106.216 +    /* calculate the power of 2 order of pfn_array_size, e.g.
 106.217         15->4 16->4 17->5 */
 106.218 -    for (i = max_pfn-1, order_nr = 0; i ; i >>= 1, order_nr++)
 106.219 +    for (i = pfn_array_size-1, order_nr = 0; i ; i >>= 1, order_nr++)
 106.220          continue;
 106.221  
 106.222      /* Setup to_send / to_fix and to_skip bitmaps */
 106.223 @@ -409,6 +446,15 @@ int xc_hvm_save(int xc_handle, int io_fd
 106.224      to_skip = malloc(BITMAP_SIZE);
 106.225  
 106.226  
 106.227 +    if (live) {
 106.228 +        /* Get qemu-dm logging dirty pages too */
 106.229 +        void *seg = init_qemu_maps(dom, BITMAP_SIZE);
 106.230 +        qemu_bitmaps[0] = seg;
 106.231 +        qemu_bitmaps[1] = seg + BITMAP_SIZE;
 106.232 +        qemu_active = 0;
 106.233 +        qemu_non_active = 1;
 106.234 +    }
 106.235 +
 106.236      hvm_buf_size = xc_domain_hvm_getcontext(xc_handle, dom, 0, 0);
 106.237      if ( hvm_buf_size == -1 )
 106.238      {
 106.239 @@ -435,7 +481,7 @@ int xc_hvm_save(int xc_handle, int io_fd
 106.240          return 1;
 106.241      }
 106.242  
 106.243 -    analysis_phase(xc_handle, dom, max_pfn, to_skip, 0);
 106.244 +    analysis_phase(xc_handle, dom, pfn_array_size, to_skip, 0);
 106.245  
 106.246  
 106.247      /* We want zeroed memory so use calloc rather than malloc. */
 106.248 @@ -465,9 +511,10 @@ int xc_hvm_save(int xc_handle, int io_fd
 106.249  
 106.250          DPRINTF("Saving HVM domain memory pages: iter %d   0%%", iter);
 106.251  
 106.252 -        while( N < max_pfn ){
 106.253 +        while( N < pfn_array_size ){
 106.254  
 106.255 -            unsigned int this_pc = (N * 100) / max_pfn;
 106.256 +            unsigned int this_pc = (N * 100) / pfn_array_size;
 106.257 +            int rc;
 106.258  
 106.259              if ((this_pc - prev_pc) >= 5) {
 106.260                  DPRINTF("\b\b\b\b%3d%%", this_pc);
 106.261 @@ -476,9 +523,9 @@ int xc_hvm_save(int xc_handle, int io_fd
 106.262  
 106.263              /* slightly wasteful to peek the whole array evey time,
 106.264                 but this is fast enough for the moment. */
 106.265 -            if (!last_iter && xc_shadow_control(
 106.266 -                    xc_handle, dom, XEN_DOMCTL_SHADOW_OP_PEEK,
 106.267 -                    to_skip, max_pfn, NULL, 0, NULL) != max_pfn) {
 106.268 +            if (!last_iter && (rc = xc_shadow_control(
 106.269 +                    xc_handle, dom, XEN_DOMCTL_SHADOW_OP_PEEK, to_skip, 
 106.270 +                    pfn_array_size, NULL, 0, NULL)) != pfn_array_size) {
 106.271                  ERROR("Error peeking HVM shadow bitmap");
 106.272                  goto out;
 106.273              }
 106.274 @@ -486,11 +533,11 @@ int xc_hvm_save(int xc_handle, int io_fd
 106.275  
 106.276              /* load pfn_batch[] with the mfn of all the pages we're doing in
 106.277                 this batch. */
 106.278 -            for (batch = 0; batch < MAX_BATCH_SIZE && N < max_pfn ; N++) {
 106.279 +            for (batch = 0; batch < MAX_BATCH_SIZE && N < pfn_array_size; N++){
 106.280  
 106.281 -                int n = permute(N, max_pfn, order_nr);
 106.282 +                int n = permute(N, pfn_array_size, order_nr);
 106.283  
 106.284 -                if (debug) {
 106.285 +                if (0&&debug) {
 106.286                      DPRINTF("%d pfn= %08lx %d \n",
 106.287                              iter, (unsigned long)n, test_bit(n, to_send));
 106.288                  }
 106.289 @@ -505,7 +552,10 @@ int xc_hvm_save(int xc_handle, int io_fd
 106.290                  /* Skip PFNs that aren't really there */
 106.291                  if ((n >= 0xa0 && n < 0xc0) /* VGA hole */
 106.292                      || (n >= (HVM_BELOW_4G_MMIO_START >> PAGE_SHIFT)
 106.293 -                        && n < (1ULL << 32) >> PAGE_SHIFT)) /* 4G MMIO hole */
 106.294 +                        && n < (1ULL << 32) >> PAGE_SHIFT) /* 4G MMIO hole */
 106.295 +                    || n == store_pfn
 106.296 +                    || n == ioreq_pfn
 106.297 +                    || n == bufioreq_pfn)
 106.298                      continue;
 106.299  
 106.300                  /*
 106.301 @@ -570,7 +620,7 @@ int xc_hvm_save(int xc_handle, int io_fd
 106.302              print_stats( xc_handle, dom, sent_this_iter, &stats, 1);
 106.303  
 106.304              DPRINTF("Total pages sent= %ld (%.2fx)\n",
 106.305 -                    total_sent, ((float)total_sent)/max_pfn );
 106.306 +                    total_sent, ((float)total_sent)/pfn_array_size );
 106.307          }
 106.308  
 106.309          if (last_iter && debug){
 106.310 @@ -597,7 +647,7 @@ int xc_hvm_save(int xc_handle, int io_fd
 106.311                  ((sent_this_iter > sent_last_iter) && RATE_IS_MAX()) ||
 106.312                  (iter >= max_iters) ||
 106.313                  (sent_this_iter+skip_this_iter < 50) ||
 106.314 -                (total_sent > max_pfn*max_factor) ) {
 106.315 +                (total_sent > pfn_array_size*max_factor) ) {
 106.316  
 106.317                  DPRINTF("Start last iteration for HVM domain\n");
 106.318                  last_iter = 1;
 106.319 @@ -608,23 +658,36 @@ int xc_hvm_save(int xc_handle, int io_fd
 106.320                      goto out;
 106.321                  }
 106.322  
 106.323 -                DPRINTF("SUSPEND shinfo %08lx eip %08lx edx %08lx\n",
 106.324 -                        info.shared_info_frame,
 106.325 +                DPRINTF("SUSPEND eip %08lx edx %08lx\n",
 106.326                          (unsigned long)ctxt.user_regs.eip,
 106.327                          (unsigned long)ctxt.user_regs.edx);
 106.328              }
 106.329  
 106.330              if (xc_shadow_control(xc_handle, dom, 
 106.331                                    XEN_DOMCTL_SHADOW_OP_CLEAN, to_send, 
 106.332 -                                  max_pfn, NULL, 0, &stats) != max_pfn) {
 106.333 +                                  pfn_array_size, NULL, 
 106.334 +                                  0, &stats) != pfn_array_size) {
 106.335                  ERROR("Error flushing shadow PT");
 106.336                  goto out;
 106.337              }
 106.338  
 106.339 +            /* Pull in the dirty bits from qemu too */
 106.340 +            if (!last_iter) {
 106.341 +                qemu_active = qemu_non_active;
 106.342 +                qemu_non_active = qemu_active ? 0 : 1;
 106.343 +                qemu_flip_buffer(dom, qemu_active);
 106.344 +                for (j = 0; j < BITMAP_SIZE / sizeof(unsigned long); j++) {
 106.345 +                    to_send[j] |= qemu_bitmaps[qemu_non_active][j];
 106.346 +                    qemu_bitmaps[qemu_non_active][j] = 0;
 106.347 +                }
 106.348 +            } else {
 106.349 +                for (j = 0; j < BITMAP_SIZE / sizeof(unsigned long); j++) 
 106.350 +                    to_send[j] |= qemu_bitmaps[qemu_active][j];
 106.351 +            }
 106.352 +
 106.353              sent_last_iter = sent_this_iter;
 106.354  
 106.355              print_stats(xc_handle, dom, sent_this_iter, &stats, 1);
 106.356 -
 106.357          }
 106.358  
 106.359  
 106.360 @@ -640,20 +703,6 @@ int xc_hvm_save(int xc_handle, int io_fd
 106.361          goto out;
 106.362      }
 106.363  
 106.364 -    if ( (rec_size = xc_domain_hvm_getcontext(xc_handle, dom, hvm_buf, 
 106.365 -                                              hvm_buf_size)) == -1) {
 106.366 -        ERROR("HVM:Could not get hvm buffer");
 106.367 -        goto out;
 106.368 -    }
 106.369 -
 106.370 -    if (!write_exact(io_fd, &rec_size, sizeof(uint32_t))) {
 106.371 -        ERROR("error write hvm buffer size");
 106.372 -        goto out;
 106.373 -    }
 106.374 -
 106.375 -    if ( !write_exact(io_fd, hvm_buf, rec_size) ) {
 106.376 -        ERROR("write HVM info failed!\n");
 106.377 -    }
 106.378  
 106.379      /* save vcpu/vmcs context */
 106.380      if (!write_exact(io_fd, &nr_vcpus, sizeof(uint32_t))) {
 106.381 @@ -682,12 +731,21 @@ int xc_hvm_save(int xc_handle, int io_fd
 106.382          }
 106.383      }
 106.384  
 106.385 -    /* Shared-info pfn */
 106.386 -    if (!write_exact(io_fd, &(shared_info_frame), sizeof(uint32_t)) ) {
 106.387 -        ERROR("write shared-info pfn failed!\n");
 106.388 +    if ( (rec_size = xc_domain_hvm_getcontext(xc_handle, dom, hvm_buf, 
 106.389 +                                              hvm_buf_size)) == -1) {
 106.390 +        ERROR("HVM:Could not get hvm buffer");
 106.391          goto out;
 106.392      }
 106.393 - 
 106.394 +
 106.395 +    if (!write_exact(io_fd, &rec_size, sizeof(uint32_t))) {
 106.396 +        ERROR("error write hvm buffer size");
 106.397 +        goto out;
 106.398 +    }
 106.399 +
 106.400 +    if ( !write_exact(io_fd, hvm_buf, rec_size) ) {
 106.401 +        ERROR("write HVM info failed!\n");
 106.402 +    }
 106.403 +
 106.404      /* Success! */
 106.405      rc = 0;
 106.406  
   107.1 --- a/tools/libxc/xc_linux_restore.c	Wed Mar 21 17:03:00 2007 -0500
   107.2 +++ b/tools/libxc/xc_linux_restore.c	Wed Mar 21 18:08:31 2007 -0500
   107.3 @@ -189,6 +189,7 @@ int xc_linux_restore(int xc_handle, int 
   107.4  
   107.5      uint64_t vcpumap = 1ULL;
   107.6      unsigned int max_vcpu_id = 0;
   107.7 +    int new_ctxt_format = 0;
   107.8  
   107.9      max_pfn = nr_pfns;
  107.10  
  107.11 @@ -372,6 +373,7 @@ int xc_linux_restore(int xc_handle, int 
  107.12          }
  107.13  
  107.14          if (j == -2) {
  107.15 +            new_ctxt_format = 1;
  107.16              if (!read_exact(io_fd, &max_vcpu_id, sizeof(int)) ||
  107.17                  (max_vcpu_id >= 64) ||
  107.18                  !read_exact(io_fd, &vcpumap, sizeof(uint64_t))) {
  107.19 @@ -797,6 +799,9 @@ int xc_linux_restore(int xc_handle, int 
  107.20              goto out;
  107.21          }
  107.22  
  107.23 +        if ( !new_ctxt_format )
  107.24 +            ctxt.flags |= VGCF_online;
  107.25 +
  107.26          if (i == 0) {
  107.27              /*
  107.28               * Uncanonicalise the suspend-record frame number and poke
   108.1 --- a/tools/libxc/xc_misc.c	Wed Mar 21 17:03:00 2007 -0500
   108.2 +++ b/tools/libxc/xc_misc.c	Wed Mar 21 18:08:31 2007 -0500
   108.3 @@ -33,6 +33,25 @@ int xc_readconsolering(int xc_handle,
   108.4      return ret;
   108.5  }
   108.6  
   108.7 +int xc_send_debug_keys(int xc_handle, char *keys)
   108.8 +{
   108.9 +    int ret, len = strlen(keys);
  108.10 +    DECLARE_SYSCTL;
  108.11 +
  108.12 +    sysctl.cmd = XEN_SYSCTL_debug_keys;
  108.13 +    set_xen_guest_handle(sysctl.u.debug_keys.keys, keys);
  108.14 +    sysctl.u.debug_keys.nr_keys = len;
  108.15 +
  108.16 +    if ( (ret = lock_pages(keys, len)) != 0 )
  108.17 +        return ret;
  108.18 +
  108.19 +    ret = do_sysctl(xc_handle, &sysctl);
  108.20 +
  108.21 +    unlock_pages(keys, len);
  108.22 +
  108.23 +    return ret;
  108.24 +}
  108.25 +
  108.26  int xc_physinfo(int xc_handle,
  108.27                  xc_physinfo_t *put_info)
  108.28  {
   109.1 --- a/tools/libxc/xc_private.c	Wed Mar 21 17:03:00 2007 -0500
   109.2 +++ b/tools/libxc/xc_private.c	Wed Mar 21 18:08:31 2007 -0500
   109.3 @@ -23,7 +23,7 @@ void xc_default_error_handler(const xc_e
   109.4      fprintf(stderr, "ERROR %s: %s\n", desc, err->message);
   109.5  }
   109.6  
   109.7 -const xc_error const *xc_get_last_error(void)
   109.8 +const xc_error *xc_get_last_error(void)
   109.9  {
  109.10      return &last_error;
  109.11  }
  109.12 @@ -263,6 +263,15 @@ int xc_memory_op(int xc_handle,
  109.13              goto out1;
  109.14          }
  109.15          break;
  109.16 +    case XENMEM_current_reservation:
  109.17 +    case XENMEM_maximum_reservation:
  109.18 +    case XENMEM_maximum_gpfn:
  109.19 +        if ( lock_pages(arg, sizeof(domid_t)) )
  109.20 +        {
  109.21 +            PERROR("Could not lock");
  109.22 +            goto out1;
  109.23 +        }
  109.24 +        break;
  109.25      }
  109.26  
  109.27      ret = do_xen_hypercall(xc_handle, &hypercall);
  109.28 @@ -287,6 +296,11 @@ int xc_memory_op(int xc_handle,
  109.29      case XENMEM_add_to_physmap:
  109.30          unlock_pages(arg, sizeof(struct xen_add_to_physmap));
  109.31          break;
  109.32 +    case XENMEM_current_reservation:
  109.33 +    case XENMEM_maximum_reservation:
  109.34 +    case XENMEM_maximum_gpfn:
  109.35 +        unlock_pages(arg, sizeof(domid_t));
  109.36 +        break;
  109.37      }
  109.38  
  109.39   out1:
   110.1 --- a/tools/libxc/xc_ptrace_core.c	Wed Mar 21 17:03:00 2007 -0500
   110.2 +++ b/tools/libxc/xc_ptrace_core.c	Wed Mar 21 18:08:31 2007 -0500
   110.3 @@ -390,7 +390,6 @@ map_gmfn_to_offset_elf(unsigned long gmf
   110.4  {
   110.5      /* 
   110.6       * linear search
   110.7 -     * There is no gurantee that those tables are sorted.
   110.8       */
   110.9      unsigned long i;
  110.10      if (current_is_auto_translated_physmap) {
   111.1 --- a/tools/libxc/xenctrl.h	Wed Mar 21 17:03:00 2007 -0500
   111.2 +++ b/tools/libxc/xenctrl.h	Wed Mar 21 18:08:31 2007 -0500
   111.3 @@ -467,6 +467,8 @@ int xc_readconsolering(int xc_handle,
   111.4                         unsigned int *pnr_chars,
   111.5                         int clear);
   111.6  
   111.7 +int xc_send_debug_keys(int xc_handle, char *keys);
   111.8 +
   111.9  typedef xen_sysctl_physinfo_t xc_physinfo_t;
  111.10  int xc_physinfo(int xc_handle,
  111.11                  xc_physinfo_t *info);
  111.12 @@ -770,19 +772,19 @@ typedef struct {
  111.13   * data pointed to are only valid until the next call to
  111.14   * libxc.
  111.15   */
  111.16 -const xc_error const *xc_get_last_error(void);
  111.17 +const xc_error *xc_get_last_error(void);
  111.18  
  111.19  /*
  111.20   * Clear the last error
  111.21   */
  111.22  void xc_clear_last_error(void);
  111.23  
  111.24 -typedef void (*xc_error_handler)(const xc_error const* err);
  111.25 +typedef void (*xc_error_handler)(const xc_error * const err);
  111.26  
  111.27  /*
  111.28   * The default error handler which prints to stderr
  111.29   */
  111.30 -void xc_default_error_handler(const xc_error const* err);
  111.31 +void xc_default_error_handler(const xc_error * const err);
  111.32  
  111.33  /*
  111.34   * Convert an error code into a text description
   112.1 --- a/tools/libxc/xenguest.h	Wed Mar 21 17:03:00 2007 -0500
   112.2 +++ b/tools/libxc/xenguest.h	Wed Mar 21 18:08:31 2007 -0500
   112.3 @@ -12,6 +12,7 @@
   112.4  #define XCFLAGS_LIVE      1
   112.5  #define XCFLAGS_DEBUG     2
   112.6  #define XCFLAGS_HVM       4
   112.7 +#define XCFLAGS_STDVGA    8
   112.8  
   112.9  
  112.10  /**
  112.11 @@ -31,8 +32,10 @@ int xc_linux_save(int xc_handle, int io_
  112.12   * @return 0 on success, -1 on failure
  112.13   */
  112.14  int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
  112.15 -                  uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */,
  112.16 -                  int (*suspend)(int domid));
  112.17 +                uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */,
  112.18 +                int (*suspend)(int domid),  
  112.19 +                void *(*init_qemu_maps)(int, unsigned), 
  112.20 +                void (*qemu_flip_buffer)(int, int));
  112.21  
  112.22  /**
  112.23   * This function will restore a saved domain running Linux.
  112.24 @@ -155,6 +158,8 @@ int xc_set_hvm_param(
  112.25  int xc_get_hvm_param(
  112.26      int handle, domid_t dom, int param, unsigned long *value);
  112.27  
  112.28 +int xc_hvm_drain_io(int handle, domid_t dom);
  112.29 +
  112.30  /* PowerPC specific. */
  112.31  int xc_prose_build(int xc_handle,
  112.32                     uint32_t domid,
   113.1 --- a/tools/libxc/xg_private.c	Wed Mar 21 17:03:00 2007 -0500
   113.2 +++ b/tools/libxc/xg_private.c	Wed Mar 21 18:08:31 2007 -0500
   113.3 @@ -201,7 +201,9 @@ unsigned long csum_page(void *page)
   113.4  __attribute__((weak)) 
   113.5      int xc_hvm_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
   113.6                      uint32_t max_factor, uint32_t flags,
   113.7 -                    int (*suspend)(int domid))
   113.8 +                    int (*suspend)(int domid), 
   113.9 +                    void *(*init_qemu_maps)(int, unsigned), 
  113.10 +                    void (*qemu_flip_buffer)(int, int))
  113.11  {
  113.12      errno = ENOSYS;
  113.13      return -1;
  113.14 @@ -229,6 +231,11 @@ unsigned long csum_page(void *page)
  113.15      return -ENOSYS;
  113.16  }
  113.17  
  113.18 +__attribute__((weak)) int xc_hvm_drain_io(int handle, domid_t dom)
  113.19 +{
  113.20 +    return -ENOSYS;
  113.21 +}
  113.22 +
  113.23  /*
  113.24   * Local variables:
  113.25   * mode: C
   114.1 --- a/tools/libxen/include/xen_crashdump.h	Wed Mar 21 17:03:00 2007 -0500
   114.2 +++ b/tools/libxen/include/xen_crashdump.h	Wed Mar 21 18:08:31 2007 -0500
   114.3 @@ -1,5 +1,5 @@
   114.4  /*
   114.5 - * Copyright (c) 2006, XenSource Inc.
   114.6 + * Copyright (c) 2006-2007, XenSource Inc.
   114.7   *
   114.8   * This library is free software; you can redistribute it and/or
   114.9   * modify it under the terms of the GNU Lesser General Public
  114.10 @@ -162,20 +162,6 @@ xen_crashdump_get_by_uuid(xen_session *s
  114.11  
  114.12  
  114.13  /**
  114.14 - * Create a new crashdump instance, and return its handle.
  114.15 - */
  114.16 -extern bool
  114.17 -xen_crashdump_create(xen_session *session, xen_crashdump *result, xen_crashdump_record *record);
  114.18 -
  114.19 -
  114.20 -/**
  114.21 - * Destroy the specified crashdump instance.
  114.22 - */
  114.23 -extern bool
  114.24 -xen_crashdump_destroy(xen_session *session, xen_crashdump crashdump);
  114.25 -
  114.26 -
  114.27 -/**
  114.28   * Get the uuid field of the given crashdump.
  114.29   */
  114.30  extern bool
  114.31 @@ -197,6 +183,13 @@ xen_crashdump_get_vdi(xen_session *sessi
  114.32  
  114.33  
  114.34  /**
  114.35 + * Destroy the specified crashdump
  114.36 + */
  114.37 +extern bool
  114.38 +xen_crashdump_destroy(xen_session *session, xen_crashdump self);
  114.39 +
  114.40 +
  114.41 +/**
  114.42   * Return a list of all the crashdumps known to the system.
  114.43   */
  114.44  extern bool
   115.1 --- a/tools/libxen/include/xen_vbd.h	Wed Mar 21 17:03:00 2007 -0500
   115.2 +++ b/tools/libxen/include/xen_vbd.h	Wed Mar 21 18:08:31 2007 -0500
   115.3 @@ -72,7 +72,6 @@ typedef struct xen_vbd_record
   115.4      struct xen_vm_record_opt *vm;
   115.5      struct xen_vdi_record_opt *vdi;
   115.6      char *device;
   115.7 -    char *image;
   115.8      bool bootable;
   115.9      enum xen_vbd_mode mode;
  115.10      enum xen_vbd_type type;
  115.11 @@ -358,6 +357,22 @@ xen_vbd_media_change(xen_session *sessio
  115.12  
  115.13  
  115.14  /**
  115.15 + * Hotplug the specified VBD, dynamically attaching it to the running
  115.16 + * VM
  115.17 + */
  115.18 +extern bool
  115.19 +xen_vbd_plug(xen_session *session, xen_vbd self);
  115.20 +
  115.21 +
  115.22 +/**
  115.23 + * Hot-unplug the specified VBD, dynamically unattaching it from the
  115.24 + * running VM
  115.25 + */
  115.26 +extern bool
  115.27 +xen_vbd_unplug(xen_session *session, xen_vbd self);
  115.28 +
  115.29 +
  115.30 +/**
  115.31   * Return a list of all the VBDs known to the system.
  115.32   */
  115.33  extern bool
   116.1 --- a/tools/libxen/include/xen_vdi.h	Wed Mar 21 17:03:00 2007 -0500
   116.2 +++ b/tools/libxen/include/xen_vdi.h	Wed Mar 21 18:08:31 2007 -0500
   116.3 @@ -1,5 +1,5 @@
   116.4  /*
   116.5 - * Copyright (c) 2006, XenSource Inc.
   116.6 + * Copyright (c) 2006-2007, XenSource Inc.
   116.7   *
   116.8   * This library is free software; you can redistribute it and/or
   116.9   * modify it under the terms of the GNU Lesser General Public
  116.10 @@ -22,6 +22,7 @@
  116.11  #include "xen_common.h"
  116.12  #include "xen_crashdump_decl.h"
  116.13  #include "xen_sr_decl.h"
  116.14 +#include "xen_string_string_map.h"
  116.15  #include "xen_vbd_decl.h"
  116.16  #include "xen_vdi_decl.h"
  116.17  #include "xen_vdi_type.h"
  116.18 @@ -73,11 +74,10 @@ typedef struct xen_vdi_record
  116.19      struct xen_crashdump_record_opt_set *crash_dumps;
  116.20      int64_t virtual_size;
  116.21      int64_t physical_utilisation;
  116.22 -    int64_t sector_size;
  116.23 -    char *location;
  116.24      enum xen_vdi_type type;
  116.25      bool sharable;
  116.26      bool read_only;
  116.27 +    xen_string_string_map *other_config;
  116.28  } xen_vdi_record;
  116.29  
  116.30  /**
  116.31 @@ -251,13 +251,6 @@ xen_vdi_get_physical_utilisation(xen_ses
  116.32  
  116.33  
  116.34  /**
  116.35 - * Get the sector_size field of the given VDI.
  116.36 - */
  116.37 -extern bool
  116.38 -xen_vdi_get_sector_size(xen_session *session, int64_t *result, xen_vdi vdi);
  116.39 -
  116.40 -
  116.41 -/**
  116.42   * Get the type field of the given VDI.
  116.43   */
  116.44  extern bool
  116.45 @@ -279,6 +272,13 @@ xen_vdi_get_read_only(xen_session *sessi
  116.46  
  116.47  
  116.48  /**
  116.49 + * Get the other_config field of the given VDI.
  116.50 + */
  116.51 +extern bool
  116.52 +xen_vdi_get_other_config(xen_session *session, xen_string_string_map **result, xen_vdi vdi);
  116.53 +
  116.54 +
  116.55 +/**
  116.56   * Set the name/label field of the given VDI.
  116.57   */
  116.58  extern bool
  116.59 @@ -293,13 +293,6 @@ xen_vdi_set_name_description(xen_session
  116.60  
  116.61  
  116.62  /**
  116.63 - * Set the SR field of the given VDI.
  116.64 - */
  116.65 -extern bool
  116.66 -xen_vdi_set_sr(xen_session *session, xen_vdi vdi, xen_sr sr);
  116.67 -
  116.68 -
  116.69 -/**
  116.70   * Set the virtual_size field of the given VDI.
  116.71   */
  116.72  extern bool
  116.73 @@ -321,6 +314,30 @@ xen_vdi_set_read_only(xen_session *sessi
  116.74  
  116.75  
  116.76  /**
  116.77 + * Set the other_config field of the given VDI.
  116.78 + */
  116.79 +extern bool
  116.80 +xen_vdi_set_other_config(xen_session *session, xen_vdi vdi, xen_string_string_map *other_config);
  116.81 +
  116.82 +
  116.83 +/**
  116.84 + * Add the given key-value pair to the other_config field of the given
  116.85 + * VDI.
  116.86 + */
  116.87 +extern bool
  116.88 +xen_vdi_add_to_other_config(xen_session *session, xen_vdi vdi, char *key, char *value);
  116.89 +
  116.90 +
  116.91 +/**
  116.92 + * Remove the given key and its corresponding value from the
  116.93 + * other_config field of the given VDI.  If the key is not in that Map, then
  116.94 + * do nothing.
  116.95 + */
  116.96 +extern bool
  116.97 +xen_vdi_remove_from_other_config(xen_session *session, xen_vdi vdi, char *key);
  116.98 +
  116.99 +
 116.100 +/**
 116.101   * Take an exact copy of the VDI; the snapshot lives in the same
 116.102   * Storage Repository as its parent.
 116.103   */
   117.1 --- a/tools/libxen/include/xen_vif.h	Wed Mar 21 17:03:00 2007 -0500
   117.2 +++ b/tools/libxen/include/xen_vif.h	Wed Mar 21 18:08:31 2007 -0500
   117.3 @@ -332,6 +332,22 @@ xen_vif_remove_from_qos_algorithm_params
   117.4  
   117.5  
   117.6  /**
   117.7 + * Hotplug the specified VIF, dynamically attaching it to the running
   117.8 + * VM
   117.9 + */
  117.10 +extern bool
  117.11 +xen_vif_plug(xen_session *session, xen_vif self);
  117.12 +
  117.13 +
  117.14 +/**
  117.15 + * Hot-unplug the specified VIF, dynamically unattaching it from the
  117.16 + * running VM
  117.17 + */
  117.18 +extern bool
  117.19 +xen_vif_unplug(xen_session *session, xen_vif self);
  117.20 +
  117.21 +
  117.22 +/**
  117.23   * Return a list of all the VIFs known to the system.
  117.24   */
  117.25  extern bool
   118.1 --- a/tools/libxen/include/xen_vm.h	Wed Mar 21 17:03:00 2007 -0500
   118.2 +++ b/tools/libxen/include/xen_vm.h	Wed Mar 21 18:08:31 2007 -0500
   118.3 @@ -40,39 +40,6 @@
   118.4   * The VM class.
   118.5   * 
   118.6   * A virtual machine (or 'guest').
   118.7 - * 
   118.8 - * VM booting is controlled by setting one of the two mutually exclusive
   118.9 - * groups: "PV", and "HVM".  If HVM.boot_policy is the empty string, then
  118.10 - * paravirtual domain building and booting will be used; otherwise the VM will
  118.11 - * be loaded as an HVM domain, and booted using an emulated BIOS.
  118.12 - * 
  118.13 - * When paravirtual booting is in use, the PV/bootloader field indicates the
  118.14 - * bootloader to use.  It may be "pygrub", in which case the platform's
  118.15 - * default installation of pygrub will be used, or a full path within the
  118.16 - * control domain to some other bootloader.  The other fields, PV/kernel,
  118.17 - * PV/ramdisk, PV/args and PV/bootloader_args will be passed to the bootloader
  118.18 - * unmodified, and interpretation of those fields is then specific to the
  118.19 - * bootloader itself, including the possibility that the bootloader will
  118.20 - * ignore some or all of those given values. Finally the paths of all bootable
  118.21 - * disks are added to the bootloader commandline (a disk is bootable if its
  118.22 - * VBD has the bootable flag set). There may be zero, one or many bootable
  118.23 - * disks; the bootloader decides which disk (if any) to boot from.
  118.24 - * 
  118.25 - * If the bootloader is pygrub, then the menu.lst is parsed if present in the
  118.26 - * guest's filesystem, otherwise the specified kernel and ramdisk are used, or
  118.27 - * an autodetected kernel is used if nothing is specified and autodetection is
  118.28 - * possible.  PV/args is appended to the kernel command line, no matter which
  118.29 - * mechanism is used for finding the kernel.
  118.30 - * 
  118.31 - * If PV/bootloader is empty but PV/kernel is specified, then the kernel and
  118.32 - * ramdisk values will be treated as paths within the control domain.  If both
  118.33 - * PV/bootloader and PV/kernel are empty, then the behaviour is as if
  118.34 - * PV/bootloader was specified as "pygrub".
  118.35 - * 
  118.36 - * When using HVM booting, HVM/boot_policy and HVM/boot_params specify the
  118.37 - * boot handling.  Only one policy is currently defined: "BIOS order".  In
  118.38 - * this case, HVM/boot_params should contain one key-value pair "order" = "N"
  118.39 - * where N is the string that will be passed to QEMU..
  118.40   */
  118.41  
  118.42  
  118.43 @@ -120,7 +87,6 @@ typedef struct xen_vm_record
  118.44      int64_t memory_dynamic_max;
  118.45      int64_t memory_dynamic_min;
  118.46      int64_t memory_static_min;
  118.47 -    char *vcpus_policy;
  118.48      xen_string_string_map *vcpus_params;
  118.49      int64_t vcpus_max;
  118.50      int64_t vcpus_at_startup;
  118.51 @@ -139,11 +105,7 @@ typedef struct xen_vm_record
  118.52      char *pv_bootloader_args;
  118.53      char *hvm_boot_policy;
  118.54      xen_string_string_map *hvm_boot_params;
  118.55 -    bool platform_std_vga;
  118.56 -    char *platform_serial;
  118.57 -    bool platform_localtime;
  118.58 -    bool platform_clock_offset;
  118.59 -    bool platform_enable_audio;
  118.60 +    xen_string_string_map *platform;
  118.61      char *pci_bus;
  118.62      xen_string_string_map *other_config;
  118.63      int64_t domid;
  118.64 @@ -360,13 +322,6 @@ xen_vm_get_memory_static_min(xen_session
  118.65  
  118.66  
  118.67  /**
  118.68 - * Get the VCPUs/policy field of the given VM.
  118.69 - */
  118.70 -extern bool
  118.71 -xen_vm_get_vcpus_policy(xen_session *session, char **result, xen_vm vm);
  118.72 -
  118.73 -
  118.74 -/**
  118.75   * Get the VCPUs/params field of the given VM.
  118.76   */
  118.77  extern bool
  118.78 @@ -493,38 +448,10 @@ xen_vm_get_hvm_boot_params(xen_session *
  118.79  
  118.80  
  118.81  /**
  118.82 - * Get the platform/std_VGA field of the given VM.
  118.83 - */
  118.84 -extern bool
  118.85 -xen_vm_get_platform_std_vga(xen_session *session, bool *result, xen_vm vm);
  118.86 -
  118.87 -
  118.88 -/**
  118.89 - * Get the platform/serial field of the given VM.
  118.90 + * Get the platform field of the given VM.
  118.91   */
  118.92  extern bool
  118.93 -xen_vm_get_platform_serial(xen_session *session, char **result, xen_vm vm);
  118.94 -
  118.95 -
  118.96 -/**
  118.97 - * Get the platform/localtime field of the given VM.
  118.98 - */
  118.99 -extern bool
 118.100 -xen_vm_get_platform_localtime(xen_session *session, bool *result, xen_vm vm);
 118.101 -
 118.102 -
 118.103 -/**
 118.104 - * Get the platform/clock_offset field of the given VM.
 118.105 - */
 118.106 -extern bool
 118.107 -xen_vm_get_platform_clock_offset(xen_session *session, bool *result, xen_vm vm);
 118.108 -
 118.109 -
 118.110 -/**
 118.111 - * Get the platform/enable_audio field of the given VM.
 118.112 - */
 118.113 -extern bool
 118.114 -xen_vm_get_platform_enable_audio(xen_session *session, bool *result, xen_vm vm);
 118.115 +xen_vm_get_platform(xen_session *session, xen_string_string_map **result, xen_vm vm);
 118.116  
 118.117  
 118.118  /**
 118.119 @@ -633,13 +560,6 @@ xen_vm_set_memory_static_min(xen_session
 118.120  
 118.121  
 118.122  /**
 118.123 - * Set the VCPUs/policy field of the given VM.
 118.124 - */
 118.125 -extern bool
 118.126 -xen_vm_set_vcpus_policy(xen_session *session, xen_vm vm, char *policy);
 118.127 -
 118.128 -
 118.129 -/**
 118.130   * Set the VCPUs/params field of the given VM.
 118.131   */
 118.132  extern bool
 118.133 @@ -765,38 +685,32 @@ xen_vm_remove_from_hvm_boot_params(xen_s
 118.134  
 118.135  
 118.136  /**
 118.137 - * Set the platform/std_VGA field of the given VM.
 118.138 + * Set the platform field of the given VM.
 118.139   */
 118.140  extern bool
 118.141 -xen_vm_set_platform_std_vga(xen_session *session, xen_vm vm, bool std_vga);
 118.142 -
 118.143 -
 118.144 -/**
 118.145 - * Set the platform/serial field of the given VM.
 118.146 - */
 118.147 -extern bool
 118.148 -xen_vm_set_platform_serial(xen_session *session, xen_vm vm, char *serial);
 118.149 +xen_vm_set_platform(xen_session *session, xen_vm vm, xen_string_string_map *platform);
 118.150  
 118.151  
 118.152  /**
 118.153 - * Set the platform/localtime field of the given VM.
 118.154 + * Add the given key-value pair to the platform field of the given VM.
 118.155   */
 118.156  extern bool
 118.157 -xen_vm_set_platform_localtime(xen_session *session, xen_vm vm, bool localtime);
 118.158 +xen_vm_add_to_platform(xen_session *session, xen_vm vm, char *key, char *value);
 118.159  
 118.160  
 118.161  /**
 118.162 - * Set the platform/clock_offset field of the given VM.
 118.163 + * Remove the given key and its corresponding value from the platform
 118.164 + * field of the given VM.  If the key is not in that Map, then do nothing.
 118.165   */
 118.166  extern bool
 118.167 -xen_vm_set_platform_clock_offset(xen_session *session, xen_vm vm, bool clock_offset);
 118.168 +xen_vm_remove_from_platform(xen_session *session, xen_vm vm, char *key);
 118.169  
 118.170  
 118.171  /**
 118.172 - * Set the platform/enable_audio field of the given VM.
 118.173 + * Set the PCI_bus field of the given VM.
 118.174   */
 118.175  extern bool
 118.176 -xen_vm_set_platform_enable_audio(xen_session *session, xen_vm vm, bool enable_audio);
 118.177 +xen_vm_set_pci_bus(xen_session *session, xen_vm vm, char *pci_bus);
 118.178  
 118.179  
 118.180  /**
   119.1 --- a/tools/libxen/src/xen_common.c	Wed Mar 21 17:03:00 2007 -0500
   119.2 +++ b/tools/libxen/src/xen_common.c	Wed Mar 21 18:08:31 2007 -0500
   119.3 @@ -110,7 +110,7 @@ parse_structmap_value(xen_session *, xml
   119.4  static size_t size_of_member(const abstract_type *);
   119.5  
   119.6  static const char *
   119.7 -get_val_as_string(const struct abstract_type *, void *, char *);
   119.8 +get_val_as_string(const struct abstract_type *, void *, char *, size_t);
   119.9  
  119.10  
  119.11  void
  119.12 @@ -666,8 +666,7 @@ static void parse_into(xen_session *s, x
  119.13      {
  119.14          if (!is_container_node(value_node, "value") ||
  119.15              value_node->children->type != XML_ELEMENT_NODE ||
  119.16 -            0 != strcmp((char *)value_node->children->name, "struct") ||
  119.17 -            value_node->children->children == NULL)
  119.18 +            0 != strcmp((char *)value_node->children->name, "struct"))
  119.19          {
  119.20              server_error(s,
  119.21                           "Expected Map from the server, but didn't get it");
  119.22 @@ -890,6 +889,9 @@ static size_t size_of_member(const abstr
  119.23      case REF:
  119.24          return sizeof(arbitrary_record_opt *);
  119.25  
  119.26 +    case STRUCT:
  119.27 +        return type->struct_size;
  119.28 +
  119.29      default:
  119.30          assert(false);
  119.31      }
  119.32 @@ -1183,7 +1185,8 @@ add_struct_value(const struct abstract_t
  119.33      case INT:
  119.34      case ENUM:
  119.35      {
  119.36 -        const char *val_as_string = get_val_as_string(type, value, buf);
  119.37 +        const char *val_as_string =
  119.38 +            get_val_as_string(type, value, buf, sizeof(buf));
  119.39          adder(node, key, "string", val_as_string);
  119.40      }
  119.41      break;
  119.42 @@ -1215,7 +1218,8 @@ add_struct_value(const struct abstract_t
  119.43  
  119.44              for (size_t i = 0; i < set_val->size; i++)
  119.45              {
  119.46 -                void *member_value = set_val->contents + (i * member_size);
  119.47 +                void *member_value = (char *)set_val->contents +
  119.48 +                                     (i * member_size);
  119.49                  add_struct_value(member_type, member_value,
  119.50                                   add_unnamed_value, NULL, data_node);
  119.51              }
  119.52 @@ -1254,7 +1258,7 @@ add_struct_value(const struct abstract_t
  119.53                  void *r_value = contents + (i * member_size) + r_offset;
  119.54  
  119.55                  const char *l_value_as_string =
  119.56 -                    get_val_as_string(l_type, l_value, buf);
  119.57 +                    get_val_as_string(l_type, l_value, buf, sizeof(buf));
  119.58  
  119.59                  add_struct_value(r_type, r_value, add_struct_member,
  119.60                                   l_value_as_string, struct_node);
  119.61 @@ -1270,7 +1274,8 @@ add_struct_value(const struct abstract_t
  119.62  
  119.63  
  119.64  static const char *
  119.65 -get_val_as_string(const struct abstract_type *type, void *value, char *buf)
  119.66 +get_val_as_string(const struct abstract_type *type, void *value, char *buf,
  119.67 +                  size_t bufsize)
  119.68  {
  119.69      switch (type->typename)
  119.70      {
  119.71 @@ -1304,7 +1309,7 @@ get_val_as_string(const struct abstract_
  119.72      case INT:
  119.73      {
  119.74          int64_t val = *(int64_t *)value;
  119.75 -        snprintf(buf, sizeof(buf), "%"PRId64, val);
  119.76 +        snprintf(buf, bufsize, "%"PRId64, val);
  119.77          return buf;
  119.78      }
  119.79      break;
   120.1 --- a/tools/libxen/src/xen_crashdump.c	Wed Mar 21 17:03:00 2007 -0500
   120.2 +++ b/tools/libxen/src/xen_crashdump.c	Wed Mar 21 18:08:31 2007 -0500
   120.3 @@ -1,5 +1,5 @@
   120.4  /*
   120.5 - * Copyright (c) 2006, XenSource Inc.
   120.6 + * Copyright (c) 2006-2007, XenSource Inc.
   120.7   *
   120.8   * This library is free software; you can redistribute it and/or
   120.9   * modify it under the terms of the GNU Lesser General Public
  120.10 @@ -115,37 +115,6 @@ xen_crashdump_get_by_uuid(xen_session *s
  120.11  
  120.12  
  120.13  bool
  120.14 -xen_crashdump_create(xen_session *session, xen_crashdump *result, xen_crashdump_record *record)
  120.15 -{
  120.16 -    abstract_value param_values[] =
  120.17 -        {
  120.18 -            { .type = &xen_crashdump_record_abstract_type_,
  120.19 -              .u.struct_val = record }
  120.20 -        };
  120.21 -
  120.22 -    abstract_type result_type = abstract_type_string;
  120.23 -
  120.24 -    *result = NULL;
  120.25 -    XEN_CALL_("crashdump.create");
  120.26 -    return session->ok;
  120.27 -}
  120.28 -
  120.29 -
  120.30 -bool
  120.31 -xen_crashdump_destroy(xen_session *session, xen_crashdump crashdump)
  120.32 -{
  120.33 -    abstract_value param_values[] =
  120.34 -        {
  120.35 -            { .type = &abstract_type_string,
  120.36 -              .u.string_val = crashdump }
  120.37 -        };
  120.38 -
  120.39 -    xen_call_(session, "crashdump.destroy", param_values, 1, NULL, NULL);
  120.40 -    return session->ok;
  120.41 -}
  120.42 -
  120.43 -
  120.44 -bool
  120.45  xen_crashdump_get_vm(xen_session *session, xen_vm *result, xen_crashdump crashdump)
  120.46  {
  120.47      abstract_value param_values[] =
  120.48 @@ -180,6 +149,20 @@ xen_crashdump_get_vdi(xen_session *sessi
  120.49  
  120.50  
  120.51  bool
  120.52 +xen_crashdump_destroy(xen_session *session, xen_crashdump self)
  120.53 +{
  120.54 +    abstract_value param_values[] =
  120.55 +        {
  120.56 +            { .type = &abstract_type_string,
  120.57 +              .u.string_val = self }
  120.58 +        };
  120.59 +
  120.60 +    xen_call_(session, "crashdump.destroy", param_values, 1, NULL, NULL);
  120.61 +    return session->ok;
  120.62 +}
  120.63 +
  120.64 +
  120.65 +bool
  120.66  xen_crashdump_get_all(xen_session *session, struct xen_crashdump_set **result)
  120.67  {
  120.68  
   121.1 --- a/tools/libxen/src/xen_vbd.c	Wed Mar 21 17:03:00 2007 -0500
   121.2 +++ b/tools/libxen/src/xen_vbd.c	Wed Mar 21 18:08:31 2007 -0500
   121.3 @@ -54,9 +54,6 @@ static const struct_member xen_vbd_recor
   121.4          { .key = "device",
   121.5            .type = &abstract_type_string,
   121.6            .offset = offsetof(xen_vbd_record, device) },
   121.7 -        { .key = "image",
   121.8 -          .type = &abstract_type_string,
   121.9 -          .offset = offsetof(xen_vbd_record, image) },
  121.10          { .key = "bootable",
  121.11            .type = &abstract_type_bool,
  121.12            .offset = offsetof(xen_vbd_record, bootable) },
  121.13 @@ -552,6 +549,34 @@ xen_vbd_media_change(xen_session *sessio
  121.14  
  121.15  
  121.16  bool
  121.17 +xen_vbd_plug(xen_session *session, xen_vbd self)
  121.18 +{
  121.19 +    abstract_value param_values[] =
  121.20 +        {
  121.21 +            { .type = &abstract_type_string,
  121.22 +              .u.string_val = self }
  121.23 +        };
  121.24 +
  121.25 +    xen_call_(session, "VBD.plug", param_values, 1, NULL, NULL);
  121.26 +    return session->ok;
  121.27 +}
  121.28 +
  121.29 +
  121.30 +bool
  121.31 +xen_vbd_unplug(xen_session *session, xen_vbd self)
  121.32 +{
  121.33 +    abstract_value param_values[] =
  121.34 +        {
  121.35 +            { .type = &abstract_type_string,
  121.36 +              .u.string_val = self }
  121.37 +        };
  121.38 +
  121.39 +    xen_call_(session, "VBD.unplug", param_values, 1, NULL, NULL);
  121.40 +    return session->ok;
  121.41 +}
  121.42 +
  121.43 +
  121.44 +bool
  121.45  xen_vbd_get_all(xen_session *session, struct xen_vbd_set **result)
  121.46  {
  121.47  
   122.1 --- a/tools/libxen/src/xen_vdi.c	Wed Mar 21 17:03:00 2007 -0500
   122.2 +++ b/tools/libxen/src/xen_vdi.c	Wed Mar 21 18:08:31 2007 -0500
   122.3 @@ -1,5 +1,5 @@
   122.4  /*
   122.5 - * Copyright (c) 2006, XenSource Inc.
   122.6 + * Copyright (c) 2006-2007, XenSource Inc.
   122.7   *
   122.8   * This library is free software; you can redistribute it and/or
   122.9   * modify it under the terms of the GNU Lesser General Public
  122.10 @@ -24,6 +24,7 @@
  122.11  #include "xen_crashdump.h"
  122.12  #include "xen_internal.h"
  122.13  #include "xen_sr.h"
  122.14 +#include "xen_string_string_map.h"
  122.15  #include "xen_vbd.h"
  122.16  #include "xen_vdi.h"
  122.17  #include "xen_vdi_type_internal.h"
  122.18 @@ -64,12 +65,6 @@ static const struct_member xen_vdi_recor
  122.19          { .key = "physical_utilisation",
  122.20            .type = &abstract_type_int,
  122.21            .offset = offsetof(xen_vdi_record, physical_utilisation) },
  122.22 -        { .key = "sector_size",
  122.23 -          .type = &abstract_type_int,
  122.24 -          .offset = offsetof(xen_vdi_record, sector_size) },
  122.25 -        { .key = "location",
  122.26 -          .type = &abstract_type_string,
  122.27 -          .offset = offsetof(xen_vdi_record, location) },
  122.28          { .key = "type",
  122.29            .type = &xen_vdi_type_abstract_type_,
  122.30            .offset = offsetof(xen_vdi_record, type) },
  122.31 @@ -78,7 +73,10 @@ static const struct_member xen_vdi_recor
  122.32            .offset = offsetof(xen_vdi_record, sharable) },
  122.33          { .key = "read_only",
  122.34            .type = &abstract_type_bool,
  122.35 -          .offset = offsetof(xen_vdi_record, read_only) }
  122.36 +          .offset = offsetof(xen_vdi_record, read_only) },
  122.37 +        { .key = "other_config",
  122.38 +          .type = &abstract_type_string_string_map,
  122.39 +          .offset = offsetof(xen_vdi_record, other_config) }
  122.40      };
  122.41  
  122.42  const abstract_type xen_vdi_record_abstract_type_ =
  122.43 @@ -105,6 +103,7 @@ xen_vdi_record_free(xen_vdi_record *reco
  122.44      xen_sr_record_opt_free(record->sr);
  122.45      xen_vbd_record_opt_set_free(record->vbds);
  122.46      xen_crashdump_record_opt_set_free(record->crash_dumps);
  122.47 +    xen_string_string_map_free(record->other_config);
  122.48      free(record);
  122.49  }
  122.50  
  122.51 @@ -315,22 +314,6 @@ xen_vdi_get_physical_utilisation(xen_ses
  122.52  
  122.53  
  122.54  bool
  122.55 -xen_vdi_get_sector_size(xen_session *session, int64_t *result, xen_vdi vdi)
  122.56 -{
  122.57 -    abstract_value param_values[] =
  122.58 -        {
  122.59 -            { .type = &abstract_type_string,
  122.60 -              .u.string_val = vdi }
  122.61 -        };
  122.62 -
  122.63 -    abstract_type result_type = abstract_type_int;
  122.64 -
  122.65 -    XEN_CALL_("VDI.get_sector_size");
  122.66 -    return session->ok;
  122.67 -}
  122.68 -
  122.69 -
  122.70 -bool
  122.71  xen_vdi_get_type(xen_session *session, enum xen_vdi_type *result, xen_vdi vdi)
  122.72  {
  122.73      abstract_value param_values[] =
  122.74 @@ -378,6 +361,23 @@ xen_vdi_get_read_only(xen_session *sessi
  122.75  
  122.76  
  122.77  bool
  122.78 +xen_vdi_get_other_config(xen_session *session, xen_string_string_map **result, xen_vdi vdi)
  122.79 +{
  122.80 +    abstract_value param_values[] =
  122.81 +        {
  122.82 +            { .type = &abstract_type_string,
  122.83 +              .u.string_val = vdi }
  122.84 +        };
  122.85 +
  122.86 +    abstract_type result_type = abstract_type_string_string_map;
  122.87 +
  122.88 +    *result = NULL;
  122.89 +    XEN_CALL_("VDI.get_other_config");
  122.90 +    return session->ok;
  122.91 +}
  122.92 +
  122.93 +
  122.94 +bool
  122.95  xen_vdi_set_name_label(xen_session *session, xen_vdi vdi, char *label)
  122.96  {
  122.97      abstract_value param_values[] =
  122.98 @@ -410,22 +410,6 @@ xen_vdi_set_name_description(xen_session
  122.99  
 122.100  
 122.101  bool
 122.102 -xen_vdi_set_sr(xen_session *session, xen_vdi vdi, xen_sr sr)
 122.103 -{
 122.104 -    abstract_value param_values[] =
 122.105 -        {
 122.106 -            { .type = &abstract_type_string,
 122.107 -              .u.string_val = vdi },
 122.108 -            { .type = &abstract_type_string,
 122.109 -              .u.string_val = sr }
 122.110 -        };
 122.111 -
 122.112 -    xen_call_(session, "VDI.set_SR", param_values, 2, NULL, NULL);
 122.113 -    return session->ok;
 122.114 -}
 122.115 -
 122.116 -
 122.117 -bool
 122.118  xen_vdi_set_virtual_size(xen_session *session, xen_vdi vdi, int64_t virtual_size)
 122.119  {
 122.120      abstract_value param_values[] =
 122.121 @@ -474,6 +458,56 @@ xen_vdi_set_read_only(xen_session *sessi
 122.122  
 122.123  
 122.124  bool
 122.125 +xen_vdi_set_other_config(xen_session *session, xen_vdi vdi, xen_string_string_map *other_config)
 122.126 +{
 122.127 +    abstract_value param_values[] =
 122.128 +        {
 122.129 +            { .type = &abstract_type_string,
 122.130 +              .u.string_val = vdi },
 122.131 +            { .type = &abstract_type_string_string_map,
 122.132 +              .u.set_val = (arbitrary_set *)other_config }
 122.133 +        };
 122.134 +
 122.135 +    xen_call_(session, "VDI.set_other_config", param_values, 2, NULL, NULL);
 122.136 +    return session->ok;
 122.137 +}
 122.138 +
 122.139 +
 122.140 +bool
 122.141 +xen_vdi_add_to_other_config(xen_session *session, xen_vdi vdi, char *key, char *value)
 122.142 +{
 122.143 +    abstract_value param_values[] =
 122.144 +        {
 122.145 +            { .type = &abstract_type_string,
 122.146 +              .u.string_val = vdi },
 122.147 +            { .type = &abstract_type_string,
 122.148 +              .u.string_val = key },
 122.149 +            { .type = &abstract_type_string,
 122.150 +              .u.string_val = value }
 122.151 +        };
 122.152 +
 122.153 +    xen_call_(session, "VDI.add_to_other_config", param_values, 3, NULL, NULL);
 122.154 +    return session->ok;
 122.155 +}
 122.156 +
 122.157 +
 122.158 +bool
 122.159 +xen_vdi_remove_from_other_config(xen_session *session, xen_vdi vdi, char *key)
 122.160 +{
 122.161 +    abstract_value param_values[] =
 122.162 +        {
 122.163 +            { .type = &abstract_type_string,
 122.164 +              .u.string_val = vdi },
 122.165 +            { .type = &abstract_type_string,
 122.166 +              .u.string_val = key }
 122.167 +        };
 122.168 +
 122.169 +    xen_call_(session, "VDI.remove_from_other_config", param_values, 2, NULL, NULL);
 122.170 +    return session->ok;
 122.171 +}
 122.172 +
 122.173 +
 122.174 +bool
 122.175  xen_vdi_snapshot(xen_session *session, xen_vdi *result, xen_vdi vdi)
 122.176  {
 122.177      abstract_value param_values[] =
   123.1 --- a/tools/libxen/src/xen_vif.c	Wed Mar 21 17:03:00 2007 -0500
   123.2 +++ b/tools/libxen/src/xen_vif.c	Wed Mar 21 18:08:31 2007 -0500
   123.3 @@ -500,6 +500,34 @@ xen_vif_remove_from_qos_algorithm_params
   123.4  
   123.5  
   123.6  bool
   123.7 +xen_vif_plug(xen_session *session, xen_vif self)
   123.8 +{
   123.9 +    abstract_value param_values[] =
  123.10 +        {
  123.11 +            { .type = &abstract_type_string,
  123.12 +              .u.string_val = self }
  123.13 +        };
  123.14 +
  123.15 +    xen_call_(session, "VIF.plug", param_values, 1, NULL, NULL);
  123.16 +    return session->ok;
  123.17 +}
  123.18 +
  123.19 +
  123.20 +bool
  123.21 +xen_vif_unplug(xen_session *session, xen_vif self)
  123.22 +{
  123.23 +    abstract_value param_values[] =
  123.24 +        {
  123.25 +            { .type = &abstract_type_string,
  123.26 +              .u.string_val = self }
  123.27 +        };
  123.28 +
  123.29 +    xen_call_(session, "VIF.unplug", param_values, 1, NULL, NULL);
  123.30 +    return session->ok;
  123.31 +}
  123.32 +
  123.33 +
  123.34 +bool
  123.35  xen_vif_get_all(xen_session *session, struct xen_vif_set **result)
  123.36  {
  123.37  
   124.1 --- a/tools/libxen/src/xen_vm.c	Wed Mar 21 17:03:00 2007 -0500
   124.2 +++ b/tools/libxen/src/xen_vm.c	Wed Mar 21 18:08:31 2007 -0500
   124.3 @@ -88,9 +88,6 @@ static const struct_member xen_vm_record
   124.4          { .key = "memory_static_min",
   124.5            .type = &abstract_type_int,
   124.6            .offset = offsetof(xen_vm_record, memory_static_min) },
   124.7 -        { .key = "VCPUs_policy",
   124.8 -          .type = &abstract_type_string,
   124.9 -          .offset = offsetof(xen_vm_record, vcpus_policy) },
  124.10          { .key = "VCPUs_params",
  124.11            .type = &abstract_type_string_string_map,
  124.12            .offset = offsetof(xen_vm_record, vcpus_params) },
  124.13 @@ -145,21 +142,9 @@ static const struct_member xen_vm_record
  124.14          { .key = "HVM_boot_params",
  124.15            .type = &abstract_type_string_string_map,
  124.16            .offset = offsetof(xen_vm_record, hvm_boot_params) },
  124.17 -        { .key = "platform_std_VGA",
  124.18 -          .type = &abstract_type_bool,
  124.19 -          .offset = offsetof(xen_vm_record, platform_std_vga) },
  124.20 -        { .key = "platform_serial",
  124.21 -          .type = &abstract_type_string,
  124.22 -          .offset = offsetof(xen_vm_record, platform_serial) },
  124.23 -        { .key = "platform_localtime",
  124.24 -          .type = &abstract_type_bool,
  124.25 -          .offset = offsetof(xen_vm_record, platform_localtime) },
  124.26 -        { .key = "platform_clock_offset",
  124.27 -          .type = &abstract_type_bool,
  124.28 -          .offset = offsetof(xen_vm_record, platform_clock_offset) },
  124.29 -        { .key = "platform_enable_audio",
  124.30 -          .type = &abstract_type_bool,
  124.31 -          .offset = offsetof(xen_vm_record, platform_enable_audio) },
  124.32 +        { .key = "platform",
  124.33 +          .type = &abstract_type_string_string_map,
  124.34 +          .offset = offsetof(xen_vm_record, platform) },
  124.35          { .key = "PCI_bus",
  124.36            .type = &abstract_type_string,
  124.37            .offset = offsetof(xen_vm_record, pci_bus) },
  124.38 @@ -203,7 +188,6 @@ xen_vm_record_free(xen_vm_record *record
  124.39      free(record->name_description);
  124.40      xen_vdi_record_opt_free(record->suspend_vdi);
  124.41      xen_host_record_opt_free(record->resident_on);
  124.42 -    free(record->vcpus_policy);
  124.43      xen_string_string_map_free(record->vcpus_params);
  124.44      xen_console_record_opt_set_free(record->consoles);
  124.45      xen_vif_record_opt_set_free(record->vifs);
  124.46 @@ -217,7 +201,7 @@ xen_vm_record_free(xen_vm_record *record
  124.47      free(record->pv_bootloader_args);
  124.48      free(record->hvm_boot_policy);
  124.49      xen_string_string_map_free(record->hvm_boot_params);
  124.50 -    free(record->platform_serial);
  124.51 +    xen_string_string_map_free(record->platform);
  124.52      free(record->pci_bus);
  124.53      xen_string_string_map_free(record->other_config);
  124.54      xen_vm_metrics_record_opt_free(record->metrics);
  124.55 @@ -510,23 +494,6 @@ xen_vm_get_memory_static_min(xen_session
  124.56  
  124.57  
  124.58  bool
  124.59 -xen_vm_get_vcpus_policy(xen_session *session, char **result, xen_vm vm)
  124.60 -{
  124.61 -    abstract_value param_values[] =
  124.62 -        {
  124.63 -            { .type = &abstract_type_string,
  124.64 -              .u.string_val = vm }
  124.65 -        };
  124.66 -
  124.67 -    abstract_type result_type = abstract_type_string;
  124.68 -
  124.69 -    *result = NULL;
  124.70 -    XEN_CALL_("VM.get_VCPUs_policy");
  124.71 -    return session->ok;
  124.72 -}
  124.73 -
  124.74 -
  124.75 -bool
  124.76  xen_vm_get_vcpus_params(xen_session *session, xen_string_string_map **result, xen_vm vm)
  124.77  {
  124.78      abstract_value param_values[] =
  124.79 @@ -825,23 +792,7 @@ xen_vm_get_hvm_boot_params(xen_session *
  124.80  
  124.81  
  124.82  bool
  124.83 -xen_vm_get_platform_std_vga(xen_session *session, bool *result, xen_vm vm)
  124.84 -{
  124.85 -    abstract_value param_values[] =
  124.86 -        {
  124.87 -            { .type = &abstract_type_string,
  124.88 -              .u.string_val = vm }
  124.89 -        };
  124.90 -
  124.91 -    abstract_type result_type = abstract_type_bool;
  124.92 -
  124.93 -    XEN_CALL_("VM.get_platform_std_VGA");
  124.94 -    return session->ok;
  124.95 -}
  124.96 -
  124.97 -
  124.98 -bool
  124.99 -xen_vm_get_platform_serial(xen_session *session, char **result, xen_vm vm)
 124.100 +xen_vm_get_platform(xen_session *session, xen_string_string_map **result, xen_vm vm)
 124.101  {
 124.102      abstract_value param_values[] =
 124.103          {
 124.104 @@ -849,58 +800,10 @@ xen_vm_get_platform_serial(xen_session *
 124.105                .u.string_val = vm }
 124.106          };
 124.107  
 124.108 -    abstract_type result_type = abstract_type_string;
 124.109 +    abstract_type result_type = abstract_type_string_string_map;
 124.110  
 124.111      *result = NULL;
 124.112 -    XEN_CALL_("VM.get_platform_serial");
 124.113 -    return session->ok;
 124.114 -}
 124.115 -
 124.116 -
 124.117 -bool
 124.118 -xen_vm_get_platform_localtime(xen_session *session, bool *result, xen_vm vm)
 124.119 -{
 124.120 -    abstract_value param_values[] =
 124.121 -        {
 124.122 -            { .type = &abstract_type_string,
 124.123 -              .u.string_val = vm }
 124.124 -        };
 124.125 -
 124.126 -    abstract_type result_type = abstract_type_bool;
 124.127 -
 124.128 -    XEN_CALL_("VM.get_platform_localtime");
 124.129 -    return session->ok;
 124.130 -}
 124.131 -
 124.132 -
 124.133 -bool
 124.134 -xen_vm_get_platform_clock_offset(xen_session *session, bool *result, xen_vm vm)
 124.135 -{
 124.136 -    abstract_value param_values[] =
 124.137 -        {
 124.138 -            { .type = &abstract_type_string,
 124.139 -              .u.string_val = vm }
 124.140 -        };
 124.141 -
 124.142 -    abstract_type result_type = abstract_type_bool;
 124.143 -
 124.144 -    XEN_CALL_("VM.get_platform_clock_offset");
 124.145 -    return session->ok;
 124.146 -}
 124.147 -
 124.148 -
 124.149 -bool
 124.150 -xen_vm_get_platform_enable_audio(xen_session *session, bool *result, xen_vm vm)
 124.151 -{
 124.152 -    abstract_value param_values[] =
 124.153 -        {
 124.154 -            { .type = &abstract_type_string,
 124.155 -              .u.string_val = vm }
 124.156 -        };
 124.157 -
 124.158 -    abstract_type result_type = abstract_type_bool;
 124.159 -
 124.160 -    XEN_CALL_("VM.get_platform_enable_audio");
 124.161 +    XEN_CALL_("VM.get_platform");
 124.162      return session->ok;
 124.163  }
 124.164  
 124.165 @@ -1150,22 +1053,6 @@ xen_vm_set_memory_static_min(xen_session
 124.166  
 124.167  
 124.168  bool
 124.169 -xen_vm_set_vcpus_policy(xen_session *session, xen_vm vm, char *policy)
 124.170 -{
 124.171 -    abstract_value param_values[] =
 124.172 -        {
 124.173 -            { .type = &abstract_type_string,
 124.174 -              .u.string_val = vm },
 124.175 -            { .type = &abstract_type_string,
 124.176 -              .u.string_val = policy }
 124.177 -        };
 124.178 -
 124.179 -    xen_call_(session, "VM.set_VCPUs_policy", param_values, 2, NULL, NULL);
 124.180 -    return session->ok;
 124.181 -}
 124.182 -
 124.183 -
 124.184 -bool
 124.185  xen_vm_set_vcpus_params(xen_session *session, xen_vm vm, xen_string_string_map *params)
 124.186  {
 124.187      abstract_value param_values[] =
 124.188 @@ -1442,81 +1329,67 @@ xen_vm_remove_from_hvm_boot_params(xen_s
 124.189  
 124.190  
 124.191  bool
 124.192 -xen_vm_set_platform_std_vga(xen_session *session, xen_vm vm, bool std_vga)
 124.193 +xen_vm_set_platform(xen_session *session, xen_vm vm, xen_string_string_map *platform)
 124.194  {
 124.195      abstract_value param_values[] =
 124.196          {
 124.197              { .type = &abstract_type_string,
 124.198                .u.string_val = vm },
 124.199 -            { .type = &abstract_type_bool,
 124.200 -              .u.bool_val = std_vga }
 124.201 +            { .type = &abstract_type_string_string_map,
 124.202 +              .u.set_val = (arbitrary_set *)platform }
 124.203          };
 124.204  
 124.205 -    xen_call_(session, "VM.set_platform_std_VGA", param_values, 2, NULL, NULL);
 124.206 +    xen_call_(session, "VM.set_platform", param_values, 2, NULL, NULL);
 124.207      return session->ok;
 124.208  }
 124.209  
 124.210  
 124.211  bool
 124.212 -xen_vm_set_platform_serial(xen_session *session, xen_vm vm, char *serial)
 124.213 +xen_vm_add_to_platform(xen_session *session, xen_vm vm, char *key, char *value)
 124.214  {
 124.215      abstract_value param_values[] =
 124.216          {
 124.217              { .type = &abstract_type_string,
 124.218                .u.string_val = vm },
 124.219              { .type = &abstract_type_string,
 124.220 -              .u.string_val = serial }
 124.221 +              .u.string_val = key },
 124.222 +            { .type = &abstract_type_string,
 124.223 +              .u.string_val = value }
 124.224          };
 124.225  
 124.226 -    xen_call_(session, "VM.set_platform_serial", param_values, 2, NULL, NULL);
 124.227 -    return session->ok;
 124.228 -}
 124.229 -
 124.230 -
 124.231 -bool
 124.232 -xen_vm_set_platform_localtime(xen_session *session, xen_vm vm, bool localtime)
 124.233 -{
 124.234 -    abstract_value param_values[] =
 124.235 -        {
 124.236 -            { .type = &abstract_type_string,
 124.237 -              .u.string_val = vm },
 124.238 -            { .type = &abstract_type_bool,
 124.239 -              .u.bool_val = localtime }
 124.240 -        };
 124.241 -
 124.242 -    xen_call_(session, "VM.set_platform_localtime", param_values, 2, NULL, NULL);
 124.243 +    xen_call_(session, "VM.add_to_platform", param_values, 3, NULL, NULL);
 124.244      return session->ok;
 124.245  }
 124.246  
 124.247  
 124.248  bool
 124.249 -xen_vm_set_platform_clock_offset(xen_session *session, xen_vm vm, bool clock_offset)
 124.250 +xen_vm_remove_from_platform(xen_session *session, xen_vm vm, char *key)
 124.251  {
 124.252      abstract_value param_values[] =
 124.253          {
 124.254              { .type = &abstract_type_string,
 124.255                .u.string_val = vm },
 124.256 -            { .type = &abstract_type_bool,
 124.257 -              .u.bool_val = clock_offset }
 124.258 +            { .type = &abstract_type_string,
 124.259 +              .u.string_val = key }
 124.260          };
 124.261  
 124.262 -    xen_call_(session, "VM.set_platform_clock_offset", param_values, 2, NULL, NULL);
 124.263 +    xen_call_(session, "VM.remove_from_platform", param_values, 2, NULL, NULL);
 124.264      return session->ok;
 124.265  }
 124.266  
 124.267  
 124.268  bool
 124.269 -xen_vm_set_platform_enable_audio(xen_session *session, xen_vm vm, bool enable_audio)
 124.270 +xen_vm_set_pci_bus(xen_session *session, xen_vm vm, char *pci_bus)
 124.271  {
 124.272      abstract_value param_values[] =
 124.273          {
 124.274              { .type = &abstract_type_string,
 124.275                .u.string_val = vm },
 124.276 -            { .type = &abstract_type_bool,
 124.277 -              .u.bool_val = enable_audio }
 124.278 +            { .type = &abstract_type_string,
 124.279 +              .u.string_val = pci_bus }
 124.280          };
 124.281  
 124.282 -    xen_call_(session, "VM.set_platform_enable_audio", param_values, 2, NULL, NULL);
 124.283 +    xen_call_(session, "VM.set_PCI_bus", param_values, 2, NULL, NULL);
 124.284      return session->ok;
 124.285  }
 124.286  
   125.1 --- a/tools/libxen/test/test_bindings.c	Wed Mar 21 17:03:00 2007 -0500
   125.2 +++ b/tools/libxen/test/test_bindings.c	Wed Mar 21 18:08:31 2007 -0500
   125.3 @@ -373,8 +373,9 @@ static xen_vm create_new_vm(xen_session 
   125.4              .memory_dynamic_max = 256,
   125.5              .memory_dynamic_min = 128,
   125.6              .memory_static_min = 128,
   125.7 -            .vcpus_policy = "credit",
   125.8              .vcpus_params = vcpus_params,
   125.9 +            .vcpus_max = 4,
  125.10 +            .vcpus_at_startup = 2,
  125.11              .actions_after_shutdown = XEN_ON_NORMAL_EXIT_DESTROY,
  125.12              .actions_after_reboot = XEN_ON_NORMAL_EXIT_RESTART,
  125.13              .actions_after_crash = XEN_ON_CRASH_BEHAVIOUR_PRESERVE,
  125.14 @@ -420,8 +421,7 @@ static xen_vm create_new_vm(xen_session 
  125.15              .name_label = "MyRootFS",
  125.16              .name_description = "MyRootFS description",
  125.17              .sr = &sr_record,
  125.18 -            .virtual_size = (1 << 21),  // 1GiB / 512 bytes/sector
  125.19 -            .sector_size = 512,
  125.20 +            .virtual_size = (INT64_C(1) << 30),  // 1GiB
  125.21              .type = XEN_VDI_TYPE_SYSTEM,
  125.22              .sharable = false,
  125.23              .read_only = false
   126.1 --- a/tools/python/scripts/test_hvm_create.py	Wed Mar 21 17:03:00 2007 -0500
   126.2 +++ b/tools/python/scripts/test_hvm_create.py	Wed Mar 21 18:08:31 2007 -0500
   126.3 @@ -39,14 +39,13 @@ vm_cfg = {
   126.4  local_vdi_cfg = {
   126.5      'name_label': 'gentoo.hvm',
   126.6      'name_description': '',
   126.7 -    'location': 'file:/root/gentoo.amd64.hvm.img',
   126.8      'virtual_size': 0,
   126.9 -    'sector_size': 0,
  126.10      'type': 'system',
  126.11      'parent': '',
  126.12      'SR_name': 'Local',
  126.13      'sharable': False,
  126.14      'read_only': False,
  126.15 +    'other_config': {'location': 'file:/root/gentoo.amd64.hvm.img'},
  126.16  }    
  126.17  
  126.18  local_vbd_cfg = {
   127.1 --- a/tools/python/scripts/test_vm_create.py	Wed Mar 21 17:03:00 2007 -0500
   127.2 +++ b/tools/python/scripts/test_vm_create.py	Wed Mar 21 18:08:31 2007 -0500
   127.3 @@ -39,8 +39,7 @@ vm_cfg = {
   127.4  vdi_cfg = {
   127.5      'name_label': 'API_VDI',
   127.6      'name_description': '',
   127.7 -    'virtual_size': 100 * 1024 * 1024,
   127.8 -    'sector_size': 1024,
   127.9 +    'virtual_size': 100 * 1024 * 1024 * 1024,
  127.10      'type': 'system',
  127.11      'parent': '',
  127.12      'SR_name': 'QCoW',
  127.13 @@ -60,14 +59,13 @@ vbd_cfg = {
  127.14  local_vdi_cfg = {
  127.15      'name_label': 'gentoo.amd64.img',
  127.16      'name_description': '',
  127.17 -    'location': 'file:/root/gentoo.amd64.img',
  127.18      'virtual_size': 0,
  127.19 -    'sector_size': 0,
  127.20      'type': 'system',
  127.21      'parent': '',
  127.22      'SR_name': 'Local',
  127.23      'sharable': False,
  127.24      'read_only': False,
  127.25 +    'other_config': {'location': 'file:/root/gentoo.amd64.img'},
  127.26  }    
  127.27  
  127.28  local_vbd_cfg = {
   128.1 --- a/tools/python/scripts/xapi.py	Wed Mar 21 17:03:00 2007 -0500
   128.2 +++ b/tools/python/scripts/xapi.py	Wed Mar 21 18:08:31 2007 -0500
   128.3 @@ -40,8 +40,7 @@ VM_LIST_FORMAT = '%(name_label)-18s %(me
   128.4                   ' %(power_state)-10s %(uuid)-36s'
   128.5  SR_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(physical_size)-10s' \
   128.6                   '%(type)-10s'
   128.7 -VDI_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(virtual_size)-8s '\
   128.8 -                  '%(sector_size)-8s'
   128.9 +VDI_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(virtual_size)-8s'
  128.10  VBD_LIST_FORMAT = '%(device)-6s %(uuid)-36s %(VDI)-8s'
  128.11  TASK_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(status)-8s %(progress)-4s'
  128.12  VIF_LIST_FORMAT = '%(name)-8s %(device)-7s %(uuid)-36s %(MAC)-10s'
  128.13 @@ -96,12 +95,9 @@ OPTIONS = {
  128.14      
  128.15      'vdi-create': [(('--name-label',), {'help': 'Name for VDI'}),
  128.16                     (('--name-description',), {'help': 'Description for VDI'}),
  128.17 -                   (('--sector-size',), {'type': 'int',
  128.18 -                                         'help': 'Sector size',
  128.19 -                                         'default': 0}),
  128.20                     (('--virtual-size',), {'type': 'int',
  128.21                                            'default': 0,
  128.22 -                                          'help': 'Size of VDI in sectors'}),
  128.23 +                                          'help': 'Size of VDI in bytes'}),
  128.24                     (('--type',), {'choices': ['system', 'user', 'ephemeral'],
  128.25                                    'default': 'system',
  128.26                                    'help': 'VDI type'}),
  128.27 @@ -569,8 +565,7 @@ def xapi_vdi_list(args, async = False):
  128.28      if not is_long:
  128.29          print VDI_LIST_FORMAT % {'name_label': 'VDI Label',
  128.30                                   'uuid' : 'UUID',
  128.31 -                                 'virtual_size': 'Bytes',
  128.32 -                                 'sector_size': 'Sector Size'}
  128.33 +                                 'virtual_size': 'Bytes'}
  128.34          
  128.35          for vdi in vdis:
  128.36              vdi_struct = execute(server, 'VDI.get_record', (session, vdi))
   129.1 --- a/tools/python/scripts/xapi.vdicfg.py	Wed Mar 21 17:03:00 2007 -0500
   129.2 +++ b/tools/python/scripts/xapi.vdicfg.py	Wed Mar 21 18:08:31 2007 -0500
   129.3 @@ -1,7 +1,6 @@
   129.4  name_label = 'VDI 1'
   129.5  name_description = ''
   129.6 -virtual_size = 10 * 1024 * 1024
   129.7 -sector_size = 1024
   129.8 +virtual_size = 10 * 1024 * 1024 * 1024
   129.9  type = 'system'
  129.10  sharable = False
  129.11  read_only = False
   130.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Wed Mar 21 17:03:00 2007 -0500
   130.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Wed Mar 21 18:08:31 2007 -0500
   130.3 @@ -47,20 +47,24 @@ static PyObject *dom_op(XcObject *self, 
   130.4  static PyObject *pyxc_error_to_exception(void)
   130.5  {
   130.6      PyObject *pyerr;
   130.7 -    const xc_error const *err = xc_get_last_error();
   130.8 +    const xc_error *err = xc_get_last_error();
   130.9      const char *desc = xc_error_code_to_desc(err->code);
  130.10  
  130.11 -    if (err->code == XC_ERROR_NONE)
  130.12 +    if ( err->code == XC_ERROR_NONE )
  130.13          return PyErr_SetFromErrno(xc_error_obj);
  130.14  
  130.15 -    if (err->message[0] != '\0')
  130.16 +    if ( err->message[0] != '\0' )
  130.17  	pyerr = Py_BuildValue("(iss)", err->code, desc, err->message);
  130.18      else
  130.19  	pyerr = Py_BuildValue("(is)", err->code, desc);
  130.20  
  130.21      xc_clear_last_error();
  130.22  
  130.23 -    PyErr_SetObject(xc_error_obj, pyerr);
  130.24 +    if ( pyerr != NULL )
  130.25 +    {
  130.26 +        PyErr_SetObject(xc_error_obj, pyerr);
  130.27 +        Py_DECREF(pyerr);
  130.28 +    }
  130.29  
  130.30      return NULL;
  130.31  }
  130.32 @@ -70,13 +74,13 @@ static PyObject *pyxc_domain_dumpcore(Xc
  130.33      uint32_t dom;
  130.34      char *corefile;
  130.35  
  130.36 -    if (!PyArg_ParseTuple(args, "is", &dom, &corefile))
  130.37 +    if ( !PyArg_ParseTuple(args, "is", &dom, &corefile) )
  130.38          return NULL;
  130.39  
  130.40      if ( (corefile == NULL) || (corefile[0] == '\0') )
  130.41          return NULL;
  130.42  
  130.43 -    if (xc_domain_dumpcore(self->xc_handle, dom, corefile) != 0)
  130.44 +    if ( xc_domain_dumpcore(self->xc_handle, dom, corefile) != 0 )
  130.45          return pyxc_error_to_exception();
  130.46      
  130.47      Py_INCREF(zero);
  130.48 @@ -168,10 +172,10 @@ static PyObject *pyxc_domain_shutdown(Xc
  130.49  {
  130.50      uint32_t dom, reason;
  130.51  
  130.52 -    if (!PyArg_ParseTuple(args, "ii", &dom, &reason))
  130.53 +    if ( !PyArg_ParseTuple(args, "ii", &dom, &reason) )
  130.54        return NULL;
  130.55  
  130.56 -    if (xc_domain_shutdown(self->xc_handle, dom, reason) != 0)
  130.57 +    if ( xc_domain_shutdown(self->xc_handle, dom, reason) != 0 )
  130.58          return pyxc_error_to_exception();
  130.59      
  130.60      Py_INCREF(zero);
  130.61 @@ -183,10 +187,10 @@ static PyObject *pyxc_domain_resume(XcOb
  130.62      uint32_t dom;
  130.63      int fast;
  130.64  
  130.65 -    if (!PyArg_ParseTuple(args, "ii", &dom, &fast))
  130.66 +    if ( !PyArg_ParseTuple(args, "ii", &dom, &fast) )
  130.67          return NULL;
  130.68  
  130.69 -    if (xc_domain_resume(self->xc_handle, dom, fast) != 0)
  130.70 +    if ( xc_domain_resume(self->xc_handle, dom, fast) != 0 )
  130.71          return pyxc_error_to_exception();
  130.72  
  130.73      Py_INCREF(zero);
  130.74 @@ -282,7 +286,7 @@ static PyObject *pyxc_domain_getinfo(XcO
  130.75                                       PyObject *args,
  130.76                                       PyObject *kwds)
  130.77  {
  130.78 -    PyObject *list, *info_dict;
  130.79 +    PyObject *list, *info_dict, *pyhandle;
  130.80  
  130.81      uint32_t first_dom = 0;
  130.82      int max_doms = 1024, nr_doms, i, j;
  130.83 @@ -308,26 +312,34 @@ static PyObject *pyxc_domain_getinfo(XcO
  130.84      list = PyList_New(nr_doms);
  130.85      for ( i = 0 ; i < nr_doms; i++ )
  130.86      {
  130.87 -        PyObject *pyhandle = PyList_New(sizeof(xen_domain_handle_t));
  130.88 +        info_dict = Py_BuildValue(
  130.89 +            "{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
  130.90 +            ",s:L,s:L,s:L,s:i,s:i}",
  130.91 +            "domid",           (int)info[i].domid,
  130.92 +            "online_vcpus",    info[i].nr_online_vcpus,
  130.93 +            "max_vcpu_id",     info[i].max_vcpu_id,
  130.94 +            "hvm",             info[i].hvm,
  130.95 +            "dying",           info[i].dying,
  130.96 +            "crashed",         info[i].crashed,
  130.97 +            "shutdown",        info[i].shutdown,
  130.98 +            "paused",          info[i].paused,
  130.99 +            "blocked",         info[i].blocked,
 130.100 +            "running",         info[i].running,
 130.101 +            "mem_kb",          (long long)info[i].nr_pages*(XC_PAGE_SIZE/1024),
 130.102 +            "cpu_time",        (long long)info[i].cpu_time,
 130.103 +            "maxmem_kb",       (long long)info[i].max_memkb,
 130.104 +            "ssidref",         (int)info[i].ssidref,
 130.105 +            "shutdown_reason", info[i].shutdown_reason);
 130.106 +        pyhandle = PyList_New(sizeof(xen_domain_handle_t));
 130.107 +        if ( (pyhandle == NULL) || (info_dict == NULL) )
 130.108 +        {
 130.109 +            Py_DECREF(list);
 130.110 +            if ( pyhandle  != NULL ) { Py_DECREF(pyhandle);  }
 130.111 +            if ( info_dict != NULL ) { Py_DECREF(info_dict); }
 130.112 +            return NULL;
 130.113 +        }
 130.114          for ( j = 0; j < sizeof(xen_domain_handle_t); j++ )
 130.115              PyList_SetItem(pyhandle, j, PyInt_FromLong(info[i].handle[j]));
 130.116 -        info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
 130.117 -                                  ",s:l,s:L,s:l,s:i,s:i}",
 130.118 -                                  "domid",       info[i].domid,
 130.119 -                                  "online_vcpus", info[i].nr_online_vcpus,
 130.120 -                                  "max_vcpu_id", info[i].max_vcpu_id,
 130.121 -                                  "hvm",       info[i].hvm,
 130.122 -                                  "dying",     info[i].dying,
 130.123 -                                  "crashed",   info[i].crashed,
 130.124 -                                  "shutdown",  info[i].shutdown,
 130.125 -                                  "paused",    info[i].paused,
 130.126 -                                  "blocked",   info[i].blocked,
 130.127 -                                  "running",   info[i].running,
 130.128 -                                  "mem_kb",    info[i].nr_pages*(XC_PAGE_SIZE/1024),
 130.129 -                                  "cpu_time",  info[i].cpu_time,
 130.130 -                                  "maxmem_kb", info[i].max_memkb,
 130.131 -                                  "ssidref",   info[i].ssidref,
 130.132 -                                  "shutdown_reason", info[i].shutdown_reason);
 130.133          PyDict_SetItemString(info_dict, "handle", pyhandle);
 130.134          Py_DECREF(pyhandle);
 130.135          PyList_SetItem(list, i, info_dict);
 130.136 @@ -1007,6 +1019,24 @@ static PyObject *pyxc_domain_send_trigge
 130.137      return zero;
 130.138  }
 130.139  
 130.140 +static PyObject *pyxc_send_debug_keys(XcObject *self,
 130.141 +                                      PyObject *args,
 130.142 +                                      PyObject *kwds)
 130.143 +{
 130.144 +    char *keys;
 130.145 +
 130.146 +    static char *kwd_list[] = { "keys", NULL };
 130.147 +
 130.148 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "s", kwd_list, &keys) )
 130.149 +        return NULL;
 130.150 +
 130.151 +    if ( xc_send_debug_keys(self->xc_handle, keys) != 0 )
 130.152 +        return pyxc_error_to_exception();
 130.153 +
 130.154 +    Py_INCREF(zero);
 130.155 +    return zero;
 130.156 +}
 130.157 +
 130.158  static PyObject *dom_op(XcObject *self, PyObject *args,
 130.159                          int (*fn)(int, uint32_t))
 130.160  {
 130.161 @@ -1380,6 +1410,12 @@ static PyMethodDef pyxc_methods[] = {
 130.162        " vcpu    [int]: VCPU to be sent trigger.\n"
 130.163        "Returns: [int] 0 on success; -1 on error.\n" },
 130.164  
 130.165 +    { "send_debug_keys",
 130.166 +      (PyCFunction)pyxc_send_debug_keys,
 130.167 +      METH_VARARGS | METH_KEYWORDS, "\n"
 130.168 +      "Inject debug keys into Xen.\n"
 130.169 +      " keys    [str]: String of keys to inject.\n" },
 130.170 +
 130.171  #ifdef __powerpc__
 130.172      { "arch_alloc_real_mode_area", 
 130.173        (PyCFunction)pyxc_alloc_real_mode_area, 
   131.1 --- a/tools/python/xen/util/blkif.py	Wed Mar 21 17:03:00 2007 -0500
   131.2 +++ b/tools/python/xen/util/blkif.py	Wed Mar 21 18:08:31 2007 -0500
   131.3 @@ -66,16 +66,23 @@ def blkdev_segment(name):
   131.4                  'type'         : 'Disk' }
   131.5      return val
   131.6  
   131.7 -def blkdev_uname_to_file(uname):
   131.8 -    """Take a blkdev uname and return the corresponding filename."""
   131.9 -    fn = None
  131.10 +def _parse_uname(uname):
  131.11 +    fn = taptype = None
  131.12      if uname.find(":") != -1:
  131.13          (typ, fn) = uname.split(":", 1)
  131.14          if typ == "phy" and not fn.startswith("/"):
  131.15              fn = "/dev/%s" %(fn,)
  131.16          if typ == "tap":
  131.17 -            (typ, fn) = fn.split(":", 1)
  131.18 -    return fn
  131.19 +            (taptype, fn) = fn.split(":", 1)
  131.20 +    return (fn, taptype)
  131.21 +
  131.22 +def blkdev_uname_to_file(uname):
  131.23 +    """Take a blkdev uname and return the corresponding filename."""
  131.24 +    return _parse_uname(uname)[0]
  131.25 +
  131.26 +def blkdev_uname_to_taptype(uname):
  131.27 +    """Take a blkdev uname and return the blktap type."""
  131.28 +    return _parse_uname(uname)[1]
  131.29  
  131.30  def mount_mode(name):
  131.31      mode = None
   132.1 --- a/tools/python/xen/util/xmlrpclib2.py	Wed Mar 21 17:03:00 2007 -0500
   132.2 +++ b/tools/python/xen/util/xmlrpclib2.py	Wed Mar 21 18:08:31 2007 -0500
   132.3 @@ -200,6 +200,18 @@ class TCPXMLRPCServer(SocketServer.Threa
   132.4              else:
   132.5                  response = self._dispatch(method, params)
   132.6  
   132.7 +            if self.xenapi and \
   132.8 +               (response is None or
   132.9 +                not isinstance(response, dict) or
  132.10 +                'Status' not in response):
  132.11 +                log.exception('Internal error handling %s: Invalid result %s',
  132.12 +                              method, response)
  132.13 +                response = { "Status": "Failure",
  132.14 +                             "ErrorDescription":
  132.15 +                             ['INTERNAL_ERROR',
  132.16 +                              'Invalid result %s handling %s' %
  132.17 +                              (response, method)]}
  132.18 +
  132.19              # With either Unicode or normal strings, we can only transmit
  132.20              # \t, \n, \r, \u0020-\ud7ff, \ue000-\ufffd, and \u10000-\u10ffff
  132.21              # in an XML document.  xmlrpclib does not escape these values
  132.22 @@ -215,24 +227,30 @@ class TCPXMLRPCServer(SocketServer.Threa
  132.23              response = xmlrpclib.dumps(response,
  132.24                                         methodresponse=1,
  132.25                                         allow_none=1)
  132.26 -        except xmlrpclib.Fault, fault:
  132.27 -            response = xmlrpclib.dumps(fault)
  132.28          except Exception, exn:
  132.29 -            if self.xenapi:
  132.30 -                if _is_not_supported(exn):
  132.31 -                    errdesc = ['MESSAGE_METHOD_UNKNOWN', method]
  132.32 +            try:
  132.33 +                if self.xenapi:
  132.34 +                    if _is_not_supported(exn):
  132.35 +                         errdesc = ['MESSAGE_METHOD_UNKNOWN', method]
  132.36 +                    else:
  132.37 +                         log.exception('Internal error handling %s', method)
  132.38 +                         errdesc = ['INTERNAL_ERROR', str(exn)]
  132.39 +
  132.40 +                    response = xmlrpclib.dumps(
  132.41 +                          ({ "Status": "Failure",
  132.42 +                             "ErrorDescription": errdesc },),
  132.43 +                          methodresponse = 1)
  132.44                  else:
  132.45 -                    log.exception('Internal error handling %s', method)
  132.46 -                    errdesc = ['INTERNAL_ERROR', str(exn)]
  132.47 -                response = xmlrpclib.dumps(
  132.48 -                    ({ "Status": "Failure",
  132.49 -                       "ErrorDescription": errdesc },),
  132.50 -                    methodresponse = 1)
  132.51 -            else:
  132.52 -                log.exception('Internal error handling %s', method)
  132.53 -                import xen.xend.XendClient
  132.54 -                response = xmlrpclib.dumps(
  132.55 -                    xmlrpclib.Fault(xen.xend.XendClient.ERROR_INTERNAL, str(exn)))
  132.56 +                    import xen.xend.XendClient
  132.57 +                    if isinstance(exn, xmlrpclib.Fault):
  132.58 +                        response = xmlrpclib.dumps(exn)
  132.59 +                    else:
  132.60 +                        log.exception('Internal error handling %s', method)
  132.61 +                        response = xmlrpclib.dumps(
  132.62 +                            xmlrpclib.Fault(xen.xend.XendClient.ERROR_INTERNAL, str(exn)))
  132.63 +            except:
  132.64 +                log.exception('Internal error handling error')
  132.65 +
  132.66          return response
  132.67  
  132.68  
  132.69 @@ -241,7 +259,7 @@ def _is_not_supported(exn):
  132.70      try:
  132.71          m = notSupportedRE.search(exn[0])
  132.72          return m is not None
  132.73 -    except TypeError, e:
  132.74 +    except:
  132.75          return False
  132.76  
  132.77  
   133.1 --- a/tools/python/xen/xend/XendAPI.py	Wed Mar 21 17:03:00 2007 -0500
   133.2 +++ b/tools/python/xen/xend/XendAPI.py	Wed Mar 21 18:08:31 2007 -0500
   133.3 @@ -31,10 +31,14 @@ from xen.xend.XendError import *
   133.4  from xen.xend.XendClient import ERROR_INVALID_DOMAIN
   133.5  from xen.xend.XendLogging import log
   133.6  from xen.xend.XendTask import XendTask
   133.7 +from xen.xend.XendVMMetrics import XendVMMetrics
   133.8  
   133.9  from xen.xend.XendAPIConstants import *
  133.10  from xen.util.xmlrpclib2 import stringify
  133.11  
  133.12 +from xen.util.blkif import blkdev_name_to_number
  133.13 +
  133.14 +
  133.15  AUTH_NONE = 'none'
  133.16  AUTH_PAM = 'pam'
  133.17  
  133.18 @@ -192,6 +196,16 @@ def valid_vm(func):
  133.19             _check_ref(XendDomain.instance().is_valid_vm,
  133.20                        'VM', func, *args, **kwargs)
  133.21  
  133.22 +def valid_vm_metrics(func):
  133.23 +    """Decorator to verify if vm_metrics_ref is valid before calling method.
  133.24 +
  133.25 +    @param func: function with params: (self, session, vm_metrics_ref, ...)
  133.26 +    @rtype: callable object
  133.27 +    """    
  133.28 +    return lambda *args, **kwargs: \
  133.29 +           _check_ref(XendVMMetrics.is_valid_vm_metrics,
  133.30 +                      'VM_metrics', func, *args, **kwargs)
  133.31 +
  133.32  def valid_network(func):
  133.33      """Decorator to verify if network_ref is valid before calling method.
  133.34  
  133.35 @@ -400,6 +414,7 @@ class XendAPI(object):
  133.36              'host_metrics' : valid_host_metrics,
  133.37              'network'      : valid_network,
  133.38              'VM'           : valid_vm,
  133.39 +            'VM_metrics'   : valid_vm_metrics,
  133.40              'VBD'          : valid_vbd,
  133.41              'VBD_metrics'  : valid_vbd_metrics,
  133.42              'VIF'          : valid_vif,
  133.43 @@ -629,6 +644,7 @@ class XendAPI(object):
  133.44      host_attr_ro = ['software_version',
  133.45                      'resident_VMs',
  133.46                      'host_CPUs',
  133.47 +                    'cpu_configuration',
  133.48                      'metrics',
  133.49                      'capabilities',
  133.50                      'supported_bootloaders',
  133.51 @@ -638,6 +654,7 @@ class XendAPI(object):
  133.52                      'API_version_vendor_implementation']
  133.53      
  133.54      host_attr_rw = ['name_label',
  133.55 +                    'sched_policy',
  133.56                      'name_description',
  133.57                      'other_config']
  133.58  
  133.59 @@ -647,7 +664,9 @@ class XendAPI(object):
  133.60                      ('shutdown', None),
  133.61                      ('add_to_other_config', None),
  133.62                      ('remove_from_other_config', None),
  133.63 -                    ('dmesg', 'String')]
  133.64 +                    ('dmesg', 'String'),
  133.65 +                    ('get_log', 'String'),
  133.66 +                    ('send_debug_keys', None)]
  133.67      
  133.68      host_funcs = [('get_by_name_label', 'Set(host)')]
  133.69  
  133.70 @@ -676,8 +695,9 @@ class XendAPI(object):
  133.71          return xen_api_success_void()
  133.72      def host_remove_from_other_config(self, session, host_ref, key):
  133.73          node = XendNode.instance()
  133.74 -        del node.other_config[key]
  133.75 -        node.save()
  133.76 +        if key in node.other_config:
  133.77 +            del node.other_config[key]
  133.78 +            node.save()
  133.79          return xen_api_success_void()
  133.80      def host_get_API_version_major(self, _, ref):
  133.81          return xen_api_success(XEN_API_VERSION_MAJOR)
  133.82 @@ -699,7 +719,13 @@ class XendAPI(object):
  133.83          return xen_api_success(XendNode.instance().get_capabilities())
  133.84      def host_get_supported_bootloaders(self, session, host_ref):
  133.85          return xen_api_success(['pygrub'])
  133.86 -
  133.87 +    def host_get_sched_policy(self, _, host_ref):
  133.88 +        return xen_api_success(XendNode.instance().get_vcpus_policy())
  133.89 +    def host_set_sched_policy(self, _, host_ref, policy):
  133.90 +        return xen_api_todo()
  133.91 +    def host_get_cpu_configuration(self, _, host_ref):
  133.92 +        return xen_api_success(XendNode.instance().get_cpu_configuration())
  133.93 +    
  133.94      # object methods
  133.95      def host_disable(self, session, host_ref):
  133.96          XendDomain.instance().set_allow_new_domains(False)
  133.97 @@ -716,8 +742,21 @@ class XendAPI(object):
  133.98              return xen_api_error(XEND_ERROR_HOST_RUNNING)
  133.99          return xen_api_error(XEND_ERROR_UNSUPPORTED)        
 133.100  
 133.101 -    def host_dmesg(self, session, host_ref):
 133.102 -        return xen_api_success(XendDmesg.instance().info())
 133.103 +    def host_dmesg(self, session, host_ref, clear):
 133.104 +        if clear:
 133.105 +            return xen_api_success(XendDmesg.instance().clear())
 133.106 +        else:
 133.107 +            return xen_api_success(XendDmesg.instance().info())
 133.108 +
 133.109 +    def host_get_log(self, session, host_ref):
 133.110 +        log_file = open(XendLogging.getLogFilename())
 133.111 +        log_buffer = log_file.read()
 133.112 +        return xen_api_success(log_buffer)
 133.113 +
 133.114 +    def host_send_debug_keys(self, _, host_ref, keys):
 133.115 +        node = XendNode.instance()
 133.116 +        node.send_debug_keys(keys)
 133.117 +        return xen_api_success_void()
 133.118  
 133.119      def host_get_record(self, session, host_ref):
 133.120          node = XendNode.instance()
 133.121 @@ -734,9 +773,11 @@ class XendAPI(object):
 133.122                    'other_config': node.other_config,
 133.123                    'resident_VMs': dom.get_domain_refs(),
 133.124                    'host_CPUs': node.get_host_cpu_refs(),
 133.125 +                  'cpu_configuration': node.get_cpu_configuration(),
 133.126                    'metrics': node.host_metrics_uuid,
 133.127                    'capabilities': node.get_capabilities(),
 133.128 -                  'supported_bootloaders': 'pygrub'}
 133.129 +                  'supported_bootloaders': 'pygrub',
 133.130 +                  'sched_policy': node.get_vcpus_policy()}
 133.131          return xen_api_success(record)
 133.132  
 133.133      # class methods
 133.134 @@ -758,7 +799,8 @@ class XendAPI(object):
 133.135                          'modelname',
 133.136                          'stepping',
 133.137                          'flags',
 133.138 -                        'utilisation']
 133.139 +                        'utilisation',
 133.140 +                        'features']
 133.141  
 133.142      # attributes
 133.143      def _host_cpu_get(self, ref, field):
 133.144 @@ -767,6 +809,8 @@ class XendAPI(object):
 133.145  
 133.146      def host_cpu_get_host(self, _, ref):
 133.147          return xen_api_success(XendNode.instance().uuid)
 133.148 +    def host_cpu_get_features(self, _, ref):
 133.149 +        return self._host_cpu_get(ref, 'features')
 133.150      def host_cpu_get_number(self, _, ref):
 133.151          return self._host_cpu_get(ref, 'number')
 133.152      def host_cpu_get_vendor(self, _, ref):
 133.153 @@ -989,19 +1033,17 @@ class XendAPI(object):
 133.154  
 133.155      VM_attr_ro = ['power_state',
 133.156                    'resident_on',
 133.157 -                  'memory_actual',
 133.158                    'memory_static_max',                  
 133.159                    'memory_static_min',
 133.160                    'VCPUs_number',
 133.161 -                  'VCPUs_utilisation',
 133.162                    'consoles',
 133.163                    'VIFs',
 133.164                    'VBDs',
 133.165                    'VTPMs',
 133.166 -                  'PCI_bus',
 133.167                    'tools_version',
 133.168                    'domid',
 133.169                    'is_control_domain',
 133.170 +                  'metrics'
 133.171                    ]
 133.172                    
 133.173      VM_attr_rw = ['name_label',
 133.174 @@ -1011,7 +1053,6 @@ class XendAPI(object):
 133.175                    'auto_power_on',
 133.176                    'memory_dynamic_max',
 133.177                    'memory_dynamic_min',
 133.178 -                  'VCPUs_policy',
 133.179                    'VCPUs_params',
 133.180                    'actions_after_shutdown',
 133.181                    'actions_after_reboot',
 133.182 @@ -1024,12 +1065,8 @@ class XendAPI(object):
 133.183                    'PV_bootloader_args',
 133.184                    'HVM_boot_policy',
 133.185                    'HVM_boot_params',
 133.186 -                  'platform_std_VGA',
 133.187 -                  'platform_serial',
 133.188 -                  'platform_localtime',
 133.189 -                  'platform_clock_offset',
 133.190 -                  'platform_enable_audio',
 133.191 -                  'platform_keymap',
 133.192 +                  'platform',
 133.193 +                  'PCI_bus',
 133.194                    'other_config']
 133.195  
 133.196      VM_methods = [('clone', 'VM'),
 133.197 @@ -1042,8 +1079,16 @@ class XendAPI(object):
 133.198                    ('hard_reboot', None),
 133.199                    ('suspend', None),
 133.200                    ('resume', None),
 133.201 +                  ('send_sysrq', None),
 133.202 +                  ('add_to_HVM_boot_params', None),
 133.203 +                  ('remove_from_HVM_boot_params', None),
 133.204 +                  ('add_to_VCPUs_params', None),
 133.205 +                  ('remove_from_VCPUs_params', None),
 133.206 +                  ('add_to_platform', None),
 133.207 +                  ('remove_from_platform', None),
 133.208                    ('add_to_other_config', None),
 133.209 -                  ('remove_from_other_config', None)]
 133.210 +                  ('remove_from_other_config', None),
 133.211 +                  ('send_trigger', None)]
 133.212      
 133.213      VM_funcs  = [('create', 'VM'),
 133.214                   ('get_by_name_label', 'Set(VM)')]
 133.215 @@ -1058,7 +1103,6 @@ class XendAPI(object):
 133.216          'memory_dynamic_max',
 133.217          'memory_dynamic_min',
 133.218          'memory_static_min',
 133.219 -        'VCPUs_policy',
 133.220          'VCPUs_params',
 133.221          'actions_after_shutdown',
 133.222          'actions_after_reboot',
 133.223 @@ -1071,13 +1115,7 @@ class XendAPI(object):
 133.224          'PV_bootloader_args',
 133.225          'HVM_boot_policy',
 133.226          'HVM_boot_params',
 133.227 -        'platform_std_VGA',
 133.228 -        'platform_serial',
 133.229 -        'platform_localtime',
 133.230 -        'platform_clock_offset',
 133.231 -        'platform_enable_audio',
 133.232 -        'platform_keymap',
 133.233 -        'grub_cmdline',
 133.234 +        'platform',
 133.235          'PCI_bus',
 133.236          'other_config']
 133.237          
 133.238 @@ -1089,7 +1127,10 @@ class XendAPI(object):
 133.239          xd = XendDomain.instance()
 133.240          dominfo = xd.get_vm_by_uuid(vm_ref)
 133.241          dominfo.info[name] = value
 133.242 -        xd.managed_config_save(dominfo)
 133.243 +        return self._VM_save(dominfo)
 133.244 +
 133.245 +    def _VM_save(self, dominfo):
 133.246 +        XendDomain.instance().managed_config_save(dominfo)
 133.247          return xen_api_success_void()
 133.248  
 133.249      # attributes (ro)
 133.250 @@ -1099,11 +1140,7 @@ class XendAPI(object):
 133.251      
 133.252      def VM_get_resident_on(self, session, vm_ref):
 133.253          return xen_api_success(XendNode.instance().uuid)
 133.254 -    
 133.255 -    def VM_get_memory_actual(self, session, vm_ref):
 133.256 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.257 -        return xen_api_todo() # unsupported by xc
 133.258 -    
 133.259 +       
 133.260      def VM_get_memory_static_max(self, session, vm_ref):
 133.261          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.262          return xen_api_success(dom.get_memory_static_max())
 133.263 @@ -1116,10 +1153,6 @@ class XendAPI(object):
 133.264          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.265          return xen_api_success(dom.getVCpuCount())
 133.266      
 133.267 -    def VM_get_VCPUs_utilisation(self, session, vm_ref):
 133.268 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.269 -        return xen_api_success(dom.get_vcpus_util())
 133.270 -    
 133.271      def VM_get_VIFs(self, session, vm_ref):
 133.272          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.273          return xen_api_success(dom.get_vifs())
 133.274 @@ -1136,14 +1169,14 @@ class XendAPI(object):
 133.275          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.276          return xen_api_success(dom.get_consoles())
 133.277      
 133.278 -    def VM_get_PCI_bus(self, session, vm_ref):
 133.279 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.280 -        return dom.get_pci_bus()
 133.281 -    
 133.282      def VM_get_tools_version(self, session, vm_ref):
 133.283          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.284          return dom.get_tools_version()
 133.285  
 133.286 +    def VM_get_metrics(self, _, vm_ref):
 133.287 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.288 +        return xen_api_success(dom.get_metrics())
 133.289 +
 133.290      # attributes (rw)
 133.291      def VM_get_name_label(self, session, vm_ref):
 133.292          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.293 @@ -1167,11 +1200,7 @@ class XendAPI(object):
 133.294  
 133.295      def VM_get_memory_dynamic_min(self, session, vm_ref):
 133.296          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.297 -        return xen_api_success(dom.get_memory_dynamic_min())        
 133.298 -    
 133.299 -    def VM_get_VCPUs_policy(self, session, vm_ref):
 133.300 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.301 -        return xen_api_success(dom.get_vcpus_policy())
 133.302 +        return xen_api_success(dom.get_memory_dynamic_min())
 133.303      
 133.304      def VM_get_VCPUs_params(self, session, vm_ref):
 133.305          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.306 @@ -1214,29 +1243,16 @@ class XendAPI(object):
 133.307      def VM_get_HVM_boot_params(self, session, vm_ref):
 133.308          return self.VM_get('HVM_boot_params', session, vm_ref)
 133.309      
 133.310 -    def VM_get_platform_std_VGA(self, session, vm_ref):
 133.311 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.312 -        return xen_api_success(dom.get_platform_std_vga())
 133.313 -    
 133.314 -    def VM_get_platform_serial(self, session, vm_ref):
 133.315 +    def VM_get_platform(self, session, vm_ref):
 133.316          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.317 -        return xen_api_success(dom.get_platform_serial())        
 133.318 -    
 133.319 -    def VM_get_platform_localtime(self, session, vm_ref):
 133.320 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.321 -        return xen_api_success(dom.get_platform_localtime())
 133.322 +        return xen_api_success(dom.get_platform())
 133.323      
 133.324 -    def VM_get_platform_clock_offset(self, session, vm_ref):
 133.325 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.326 -        return xen_api_success(dom.get_platform_clock_offset())        
 133.327 -    
 133.328 -    def VM_get_platform_enable_audio(self, session, vm_ref):
 133.329 +    def VM_get_PCI_bus(self, session, vm_ref):
 133.330          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.331 -        return xen_api_success(dom.get_platform_enable_audio())        
 133.332 +        return dom.get_pci_bus()
 133.333      
 133.334 -    def VM_get_platform_keymap(self, session, vm_ref):
 133.335 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.336 -        return xen_api_success(dom.get_platform_keymap())
 133.337 +    def VM_set_PCI_bus(self, session, vm_ref, val):
 133.338 +        return self.VM_set('PCI_bus', session, vm_ref, val)
 133.339      
 133.340      def VM_get_other_config(self, session, vm_ref):
 133.341          return self.VM_get('other_config', session, vm_ref)        
 133.342 @@ -1253,7 +1269,7 @@ class XendAPI(object):
 133.343      def VM_set_name_label(self, session, vm_ref, label):
 133.344          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.345          dom.setName(label)
 133.346 -        return xen_api_success_void()
 133.347 +        return self._VM_save(dom)
 133.348      
 133.349      def VM_set_name_description(self, session, vm_ref, desc):
 133.350          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.351 @@ -1275,21 +1291,32 @@ class XendAPI(object):
 133.352          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.353          return xen_api_todo()
 133.354      
 133.355 -    def VM_set_VCPUs_policy(self, session, vm_ref, policy):
 133.356 +    def VM_set_VCPUs_params(self, session, vm_ref, value):
 133.357 +        return self.VM_set('vcpus_params', session, vm_ref, value)
 133.358 +
 133.359 +    def VM_add_to_VCPUs_params(self, session, vm_ref, key, value):
 133.360          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.361 -        return xen_api_todo()
 133.362 -    
 133.363 -    def VM_set_VCPUs_params(self, session, vm_ref, params):
 133.364 +        if 'vcpus_params' not in dom.info:
 133.365 +            dom.info['vcpus_params'] = {}
 133.366 +        dom.info['vcpus_params'][key] = value
 133.367 +        return self._VM_save(dom)
 133.368 +
 133.369 +    def VM_remove_from_VCPUs_params(self, session, vm_ref, key):
 133.370          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.371 -        return xen_api_todo()
 133.372 +        if 'vcpus_params' in dom.info \
 133.373 +               and key in dom.info['vcpus_params']:
 133.374 +            del dom.info['vcpus_params'][key]
 133.375 +            return self._VM_save(dom)
 133.376 +        else:
 133.377 +            return xen_api_success_void()
 133.378      
 133.379      def VM_set_actions_after_shutdown(self, session, vm_ref, action):
 133.380 -        if action not in XEN_API_ON_NORMAL_EXIST:
 133.381 +        if action not in XEN_API_ON_NORMAL_EXIT:
 133.382              return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref])
 133.383          return self.VM_set('actions_after_shutdown', session, vm_ref, action)
 133.384      
 133.385      def VM_set_actions_after_reboot(self, session, vm_ref, action):
 133.386 -        if action not in XEN_API_ON_NORMAL_EXIST:
 133.387 +        if action not in XEN_API_ON_NORMAL_EXIT:
 133.388              return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref])
 133.389          return self.VM_set('actions_after_reboot', session, vm_ref, action)
 133.390      
 133.391 @@ -1319,14 +1346,16 @@ class XendAPI(object):
 133.392          if 'HVM_boot_params' not in dom.info:
 133.393              dom.info['HVM_boot_params'] = {}
 133.394          dom.info['HVM_boot_params'][key] = value
 133.395 -        return xen_api_success_void()
 133.396 +        return self._VM_save(dom)
 133.397  
 133.398      def VM_remove_from_HVM_boot_params(self, session, vm_ref, key):
 133.399          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.400          if 'HVM_boot_params' in dom.info \
 133.401                 and key in dom.info['HVM_boot_params']:
 133.402              del dom.info['HVM_boot_params'][key]
 133.403 -        return xen_api_success_void()
 133.404 +            return self._VM_save(dom)
 133.405 +        else:
 133.406 +            return xen_api_success_void()
 133.407  
 133.408      def VM_set_PV_bootloader(self, session, vm_ref, value):
 133.409          return self.VM_set('PV_bootloader', session, vm_ref, value)
 133.410 @@ -1343,40 +1372,42 @@ class XendAPI(object):
 133.411      def VM_set_PV_bootloader_args(self, session, vm_ref, value):
 133.412          return self.VM_set('PV_bootloader_args', session, vm_ref, value)
 133.413  
 133.414 -    def VM_set_platform_std_VGA(self, session, vm_ref, value):
 133.415 -        return self.VM_set('platform_std_vga', session, vm_ref, value)
 133.416 -    
 133.417 -    def VM_set_platform_serial(self, session, vm_ref, value):
 133.418 -        return self.VM_set('platform_serial', session, vm_ref, value)
 133.419 -
 133.420 -    def VM_set_platform_keymap(self, session, vm_ref, value):
 133.421 -        return self.VM_set('platform_keymap', session, vm_ref, value)
 133.422 +    def VM_set_platform(self, session, vm_ref, value):
 133.423 +        return self.VM_set('platform', session, vm_ref, value)
 133.424      
 133.425 -    def VM_set_platform_localtime(self, session, vm_ref, value):
 133.426 -        return self.VM_set('platform_localtime', session, vm_ref, value)
 133.427 -    
 133.428 -    def VM_set_platform_clock_offset(self, session, vm_ref, value):
 133.429 -        return self.VM_set('platform_clock_offset', session, vm_ref, value)
 133.430 -    
 133.431 -    def VM_set_platform_enable_audio(self, session, vm_ref, value):
 133.432 -        return self.VM_set('platform_enable_audio', session, vm_ref, value)
 133.433 -    
 133.434 +    def VM_add_to_platform(self, session, vm_ref, key, value):
 133.435 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.436 +        plat = dom.get_platform()
 133.437 +        plat[key] = value
 133.438 +        return self.VM_set_platform(session, vm_ref, plat)
 133.439 +
 133.440 +    def VM_remove_from_platform(self, session, vm_ref, key):
 133.441 +        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.442 +        plat = dom.get_platform()
 133.443 +        if key in plat:
 133.444 +            del plat[key]
 133.445 +            return self.VM_set_platform(session, vm_ref, plat)
 133.446 +        else:
 133.447 +            return xen_api_success_void()
 133.448 +
 133.449      def VM_set_other_config(self, session, vm_ref, value):
 133.450 -        return self.VM_set('otherconfig', session, vm_ref, value)
 133.451 +        return self.VM_set('other_config', session, vm_ref, value)
 133.452  
 133.453      def VM_add_to_other_config(self, session, vm_ref, key, value):
 133.454          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.455 -        if dom and 'otherconfig' in dom.info:
 133.456 -            dom.info['otherconfig'][key] = value
 133.457 -        return xen_api_success_void()
 133.458 +        if dom and 'other_config' in dom.info:
 133.459 +            dom.info['other_config'][key] = value
 133.460 +        return self._VM_save(dom)
 133.461  
 133.462      def VM_remove_from_other_config(self, session, vm_ref, key):
 133.463          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.464 -        if dom and 'otherconfig' in dom.info \
 133.465 -               and key in dom.info['otherconfig']:
 133.466 -            del dom.info['otherconfig'][key]
 133.467 -        return xen_api_success_void()        
 133.468 -    
 133.469 +        if dom and 'other_config' in dom.info \
 133.470 +               and key in dom.info['other_config']:
 133.471 +            del dom.info['other_config'][key]
 133.472 +            return self._VM_save(dom)
 133.473 +        else:
 133.474 +            return xen_api_success_void()
 133.475 +
 133.476      # class methods
 133.477      def VM_get_all(self, session):
 133.478          refs = [d.get_uuid() for d in XendDomain.instance().list('all')]
 133.479 @@ -1417,11 +1448,8 @@ class XendAPI(object):
 133.480              'memory_static_max': xeninfo.get_memory_static_max(),
 133.481              'memory_dynamic_min': xeninfo.get_memory_dynamic_min(),
 133.482              'memory_dynamic_max': xeninfo.get_memory_dynamic_max(),
 133.483 -            'memory_actual': xeninfo.get_memory_static_min(),
 133.484 -            'VCPUs_policy': xeninfo.get_vcpus_policy(),
 133.485              'VCPUs_params': xeninfo.get_vcpus_params(),
 133.486              'VCPUs_number': xeninfo.getVCpuCount(),
 133.487 -            'VCPUs_utilisation': xeninfo.get_vcpus_util(),
 133.488              'actions_after_shutdown': xeninfo.get_on_shutdown(),
 133.489              'actions_after_reboot': xeninfo.get_on_reboot(),
 133.490              'actions_after_suspend': xeninfo.get_on_suspend(),
 133.491 @@ -1437,12 +1465,7 @@ class XendAPI(object):
 133.492              'PV_bootloader_args': xeninfo.info.get('PV_bootloader_args'),
 133.493              'HVM_boot_policy': xeninfo.info.get('HVM_boot_policy'),
 133.494              'HVM_boot_params': xeninfo.info.get('HVM_boot_params'),
 133.495 -            'platform_std_VGA': xeninfo.get_platform_std_vga(),
 133.496 -            'platform_serial': xeninfo.get_platform_serial(),
 133.497 -            'platform_localtime': xeninfo.get_platform_localtime(),
 133.498 -            'platform_clock_offset': xeninfo.get_platform_clock_offset(),
 133.499 -            'platform_enable_audio': xeninfo.get_platform_enable_audio(),
 133.500 -            'platform_keymap': xeninfo.get_platform_keymap(),
 133.501 +            'platform': xeninfo.get_platform(),
 133.502              'PCI_bus': xeninfo.get_pci_bus(),
 133.503              'tools_version': xeninfo.get_tools_version(),
 133.504              'other_config': xeninfo.info.get('other_config', {}),
 133.505 @@ -1486,10 +1509,13 @@ class XendAPI(object):
 133.506                                       start_paused = start_paused)
 133.507      
 133.508      def VM_start(self, session, vm_ref, start_paused):
 133.509 -        return XendTask.log_progress(0, 100, do_vm_func,
 133.510 -                                     "domain_start", vm_ref,
 133.511 -                                     start_paused = start_paused)
 133.512 -    
 133.513 +        try:
 133.514 +            return XendTask.log_progress(0, 100, do_vm_func,
 133.515 +                                         "domain_start", vm_ref,
 133.516 +                                         start_paused = start_paused)
 133.517 +        except HVMRequired, exn:
 133.518 +            return xen_api_error(['VM_HVM_REQUIRED', vm_ref])
 133.519 +
 133.520      def VM_suspend(self, session, vm_ref):
 133.521          return XendTask.log_progress(0, 100, do_vm_func,
 133.522                                       "domain_suspend", vm_ref)
 133.523 @@ -1498,10 +1524,56 @@ class XendAPI(object):
 133.524          return XendTask.log_progress(0, 100, do_vm_func,
 133.525                                       "domain_unpause", vm_ref)
 133.526  
 133.527 +    def VM_send_sysrq(self, _, vm_ref, req):
 133.528 +        xeninfo = XendDomain.instance().get_vm_by_uuid(vm_ref)
 133.529 +        if xeninfo.state != XEN_API_VM_POWER_STATE_RUNNING:
 133.530 +            return xen_api_error(
 133.531 +                ['VM_BAD_POWER_STATE', vm_ref,
 133.532 +                 XendDomain.POWER_STATE_NAMES[XEN_API_VM_POWER_STATE_RUNNING],
 133.533 +                 XendDomain.POWER_STATE_NAMES[xeninfo.state]])
 133.534 +        xeninfo.send_sysrq(req)
 133.535 +        return xen_api_success_void()
 133.536 +
 133.537 +
 133.538 +    def VM_send_trigger(self, _, vm_ref, trigger, vcpu):
 133.539 +        xendom = XendDomain.instance()
 133.540 +        xeninfo = xendom.get_vm_by_uuid(vm_ref)
 133.541 +        xendom.domain_send_trigger(xeninfo.getDomid(), trigger, vcpu)
 133.542 +        return xen_api_success_void()
 133.543 +        
 133.544 +
 133.545 +    # Xen API: Class VM_metrics
 133.546 +    # ----------------------------------------------------------------
 133.547 +
 133.548 +    VM_metrics_attr_ro = ['memory_actual',
 133.549 +                           'vcpus_number',
 133.550 +                           'vcpus_utilisation']
 133.551 +    VM_metrics_attr_rw = []
 133.552 +    VM_metrics_methods = []
 133.553 +
 133.554 +    def _VM_metrics_get(self, ref):
 133.555 +        return XendVMMetrics.get_by_uuid(ref)
 133.556 +
 133.557 +    def VM_metrics_get_all(self, _):
 133.558 +        return xen_api_success(XendVMMetrics.get_all())
 133.559 +
 133.560 +    def VM_metrics_get_record(self, _, ref):
 133.561 +        return xen_api_success(self._VM_metrics_get(ref).get_record())
 133.562 +
 133.563 +    def VM_metrics_get_memory_actual(self, _, ref):
 133.564 +        return xen_api_success(self._VM_metrics_get(ref).get_memory_actual())
 133.565 +
 133.566 +    def VM_metrics_get_vcpus_number(self, _, ref):
 133.567 +        return xen_api_success(self._VM_metrics_get(ref).get_vcpus_number())
 133.568 +
 133.569 +    def VM_metrics_get_vcpus_utilisation(self, _, ref):
 133.570 +        return xen_api_success(self._VM_metrics_get(ref).get_vcpus_utilisation())
 133.571 +
 133.572      # Xen API: Class VBD
 133.573      # ----------------------------------------------------------------
 133.574  
 133.575 -    VBD_attr_ro = ['metrics']
 133.576 +    VBD_attr_ro = ['metrics',
 133.577 +                   'runtime_properties']
 133.578      VBD_attr_rw = ['VM',
 133.579                     'VDI',
 133.580                     'device',
 133.581 @@ -1542,23 +1614,28 @@ class XendAPI(object):
 133.582      # class methods
 133.583      def VBD_create(self, session, vbd_struct):
 133.584          xendom = XendDomain.instance()
 133.585 +        xennode = XendNode.instance()
 133.586 +        
 133.587          if not xendom.is_valid_vm(vbd_struct['VM']):
 133.588              return xen_api_error(['HANDLE_INVALID', 'VM', vbd_struct['VM']])
 133.589          
 133.590          dom = xendom.get_vm_by_uuid(vbd_struct['VM'])
 133.591 -        vbd_ref = ''
 133.592 +        vdi = xennode.get_vdi_by_uuid(vbd_struct['VDI'])
 133.593 +        if not vdi:
 133.594 +            return xen_api_error(['HANDLE_INVALID', 'VDI', vdi_ref])
 133.595 +
 133.596 +        # new VBD via VDI/SR
 133.597 +        vdi_image = vdi.get_location()
 133.598 +
 133.599          try:
 133.600 -            # new VBD via VDI/SR
 133.601 -            vdi_ref = vbd_struct.get('VDI')
 133.602 -            vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
 133.603 -            if not vdi:
 133.604 -                return xen_api_error(['HANDLE_INVALID', 'VDI', vdi_ref])
 133.605 -            vdi_image = vdi.get_location()
 133.606              vbd_ref = XendTask.log_progress(0, 100,
 133.607                                              dom.create_vbd,
 133.608                                              vbd_struct, vdi_image)
 133.609 -        except XendError:
 133.610 -            return xen_api_todo()
 133.611 +        except XendError, e:
 133.612 +            log.exception("Error in VBD_create")
 133.613 +            return xen_api_error(['INTERNAL_ERROR', str(e)]) 
 133.614 +            
 133.615 +        vdi.addVBD(vbd_ref)
 133.616  
 133.617          xendom.managed_config_save(dom)
 133.618          return xen_api_success(vbd_ref)
 133.619 @@ -1570,7 +1647,14 @@ class XendAPI(object):
 133.620          if not vm:
 133.621              return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref])
 133.622  
 133.623 +        vdi_ref = XendDomain.instance()\
 133.624 +                  .get_dev_property_by_uuid('vbd', vbd_ref, "VDI")
 133.625 +        vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
 133.626 +
 133.627          XendTask.log_progress(0, 100, vm.destroy_vbd, vbd_ref)
 133.628 +
 133.629 +        vdi.removeVBD(vbd_ref)
 133.630 +        
 133.631          return xen_api_success_void()
 133.632  
 133.633      def _VBD_get(self, vbd_ref, prop):
 133.634 @@ -1582,6 +1666,24 @@ class XendAPI(object):
 133.635      def VBD_get_metrics(self, _, vbd_ref):
 133.636          return xen_api_success(vbd_ref)
 133.637  
 133.638 +    def VBD_get_runtime_properties(self, _, vbd_ref):
 133.639 +        xendom = XendDomain.instance()
 133.640 +        dominfo = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
 133.641 +        device = dominfo.get_dev_config_by_uuid('vbd', vbd_ref)
 133.642 +
 133.643 +        try:
 133.644 +            devid = int(device['id'])
 133.645 +            device_sxps = dominfo.getDeviceSxprs('vbd')
 133.646 +            device_dicts  = [dict(device_sxp[1][1:]) for device_sxp in device_sxps]
 133.647 +            device_dict = [device_dict
 133.648 +                           for device_dict in device_dicts
 133.649 +                           if int(device_dict['virtual-device']) == devid][0]
 133.650 +
 133.651 +            return xen_api_success(device_dict)
 133.652 +        except Exception, exn:
 133.653 +            log.exception(exn)
 133.654 +            return xen_api_success({})
 133.655 +
 133.656      # attributes (rw)
 133.657      def VBD_get_VM(self, session, vbd_ref):
 133.658          return self._VBD_get(vbd_ref, 'VM')
 133.659 @@ -1642,7 +1744,8 @@ class XendAPI(object):
 133.660      # Xen API: Class VIF
 133.661      # ----------------------------------------------------------------
 133.662  
 133.663 -    VIF_attr_ro = ['metrics']
 133.664 +    VIF_attr_ro = ['metrics',
 133.665 +                   'runtime_properties']
 133.666      VIF_attr_rw = ['device',
 133.667                     'network',
 133.668                     'VM',
 133.669 @@ -1679,18 +1782,17 @@ class XendAPI(object):
 133.670      # class methods
 133.671      def VIF_create(self, session, vif_struct):
 133.672          xendom = XendDomain.instance()
 133.673 -        if xendom.is_valid_vm(vif_struct['VM']):
 133.674 -            dom = xendom.get_vm_by_uuid(vif_struct['VM'])
 133.675 -            try:
 133.676 -                vif_ref = dom.create_vif(vif_struct)
 133.677 -                xendom.managed_config_save(dom)                
 133.678 -                return xen_api_success(vif_ref)
 133.679 -            except XendError:
 133.680 -                return xen_api_error(XEND_ERROR_TODO)
 133.681 -        else:
 133.682 +        if not xendom.is_valid_vm(vif_struct['VM']):
 133.683              return xen_api_error(['HANDLE_INVALID', 'VM', vif_struct['VM']])
 133.684  
 133.685 -
 133.686 +        dom = xendom.get_vm_by_uuid(vif_struct['VM'])
 133.687 +        try:
 133.688 +            vif_ref = dom.create_vif(vif_struct)
 133.689 +            xendom.managed_config_save(dom)
 133.690 +            return xen_api_success(vif_ref)
 133.691 +        except XendError:
 133.692 +            return xen_api_error(XEND_ERROR_TODO)
 133.693 +          
 133.694      def VIF_destroy(self, session, vif_ref):
 133.695          xendom = XendDomain.instance()
 133.696          vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
 133.697 @@ -1728,6 +1830,27 @@ class XendAPI(object):
 133.698          vifs = reduce(lambda x, y: x + y, vifs)
 133.699          return xen_api_success(vifs)
 133.700  
 133.701 +    def VIF_get_runtime_properties(self, _, vif_ref):
 133.702 +        xendom = XendDomain.instance()
 133.703 +        dominfo = xendom.get_vm_with_dev_uuid('vif', vif_ref)
 133.704 +        device = dominfo.get_dev_config_by_uuid('vif', vif_ref)
 133.705 +        
 133.706 +        try:
 133.707 +            devid = int(device['id'])
 133.708 +        
 133.709 +            device_sxps = dominfo.getDeviceSxprs('vif')
 133.710 +            device_dicts = [dict(device_sxp[1][1:])
 133.711 +                            for device_sxp in device_sxps]
 133.712 +            
 133.713 +            device_dict = [device_dict
 133.714 +                       for device_dict in device_dicts
 133.715 +                       if int(device_dict['handle']) == devid][0]
 133.716 +            
 133.717 +            return xen_api_success(device_dict)
 133.718 +        
 133.719 +        except Exception, exn:
 133.720 +            log.exception(exn)
 133.721 +            return xen_api_success({})
 133.722      
 133.723      # Xen API: Class VIF_metrics
 133.724      # ----------------------------------------------------------------
 133.725 @@ -1754,16 +1877,16 @@ class XendAPI(object):
 133.726  
 133.727      # Xen API: Class VDI
 133.728      # ----------------------------------------------------------------
 133.729 -    VDI_attr_ro = ['VBDs',
 133.730 +    VDI_attr_ro = ['SR',
 133.731 +                   'VBDs',
 133.732                     'physical_utilisation',
 133.733 -                   'sector_size',
 133.734                     'type']
 133.735      VDI_attr_rw = ['name_label',
 133.736                     'name_description',
 133.737 -                   'SR',
 133.738                     'virtual_size',
 133.739                     'sharable',
 133.740 -                   'read_only']
 133.741 +                   'read_only',
 133.742 +                   'other_config']
 133.743      VDI_attr_inst = VDI_attr_ro + VDI_attr_rw
 133.744  
 133.745      VDI_methods = [('snapshot', 'VDI')]
 133.746 @@ -1774,14 +1897,12 @@ class XendAPI(object):
 133.747          return XendNode.instance().get_vdi_by_uuid(ref)
 133.748      
 133.749      def VDI_get_VBDs(self, session, vdi_ref):
 133.750 -        return xen_api_todo()
 133.751 +        vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
 133.752 +        return xen_api_success(vdi.getVBDs())
 133.753      
 133.754      def VDI_get_physical_utilisation(self, session, vdi_ref):
 133.755          return xen_api_success(self._get_VDI(vdi_ref).
 133.756 -                               get_physical_utilisation())        
 133.757 -    
 133.758 -    def VDI_get_sector_size(self, session, vdi_ref):
 133.759 -        return xen_api_success(self._get_VDI(vdi_ref).sector_size)        
 133.760 +                               get_physical_utilisation())              
 133.761      
 133.762      def VDI_get_type(self, session, vdi_ref):
 133.763          return xen_api_success(self._get_VDI(vdi_ref).type)
 133.764 @@ -1812,9 +1933,6 @@ class XendAPI(object):
 133.765          self._get_VDI(vdi_ref).name_description = value
 133.766          return xen_api_success_void()
 133.767  
 133.768 -    def VDI_set_SR(self, session, vdi_ref, value):
 133.769 -        return xen_api_error(XEND_ERROR_UNSUPPORTED)
 133.770 -
 133.771      def VDI_set_virtual_size(self, session, vdi_ref, value):
 133.772          return xen_api_error(XEND_ERROR_UNSUPPORTED)
 133.773  
 133.774 @@ -1826,6 +1944,14 @@ class XendAPI(object):
 133.775          self._get_VDI(vdi_ref).read_only = bool(value)
 133.776          return xen_api_success_void()
 133.777  
 133.778 +    def VDI_get_other_config(self, session, vdi_ref):
 133.779 +        return xen_api_success(
 133.780 +            self._get_VDI(vdi_ref).other_config)
 133.781 +
 133.782 +    def VDI_set_other_config(self, session, vdi_ref, other_config):
 133.783 +        self._get_VDI(vdi_ref).other_config = other_config
 133.784 +        return xen_api_success_void()
 133.785 +
 133.786      # Object Methods
 133.787      def VDI_snapshot(self, session, vdi_ref):
 133.788          return xen_api_todo()
 133.789 @@ -1842,13 +1968,13 @@ class XendAPI(object):
 133.790              'name_label': image.name_label,
 133.791              'name_description': image.name_description,
 133.792              'SR': image.sr_uuid,
 133.793 -            'VBDs': [], # TODO
 133.794 +            'VBDs': image.getVBDs(),
 133.795              'virtual_size': image.virtual_size,
 133.796              'physical_utilisation': image.physical_utilisation,
 133.797 -            'sector_size': image.sector_size,
 133.798              'type': image.type,
 133.799              'sharable': image.sharable,
 133.800              'read_only': image.read_only,
 133.801 +            'other_config': image.other_config
 133.802              })
 133.803  
 133.804      # Class Functions    
 133.805 @@ -1929,7 +2055,7 @@ class XendAPI(object):
 133.806                   XendDomain.POWER_STATE_NAMES[dom.state]])
 133.807              from xen.xend.server import tpmif
 133.808              tpmif.destroy_vtpmstate(dom.getName())
 133.809 -            return xen_api_success(True)
 133.810 +            return xen_api_success_void()
 133.811          else:
 133.812              return xen_api_error(['HANDLE_INVALID', 'VM', vtpm_struct['VM']])
 133.813  
   134.1 --- a/tools/python/xen/xend/XendCheckpoint.py	Wed Mar 21 17:03:00 2007 -0500
   134.2 +++ b/tools/python/xen/xend/XendCheckpoint.py	Wed Mar 21 18:08:31 2007 -0500
   134.3 @@ -9,6 +9,7 @@ import os
   134.4  import re
   134.5  import string
   134.6  import threading
   134.7 +import fcntl
   134.8  from struct import pack, unpack, calcsize
   134.9  
  134.10  from xen.util.xpopen import xPopen3
  134.11 @@ -73,10 +74,15 @@ def save(fd, dominfo, network, live, dst
  134.12          write_exact(fd, config, "could not write guest state file: config")
  134.13  
  134.14          image_cfg = dominfo.info.get('image', {})
  134.15 -        hvm = image_cfg.has_key('hvm')
  134.16 +        hvm = dominfo.info.is_hvm()
  134.17 +        stdvga = 0
  134.18  
  134.19          if hvm:
  134.20              log.info("save hvm domain")
  134.21 +            if dominfo.info['platform'].has_key('stdvga'):
  134.22 +                if dominfo.info['platform']['stdvga'] == 1:
  134.23 +                    stdvga = 1
  134.24 +
  134.25          # xc_save takes three customization parameters: maxit, max_f, and
  134.26          # flags the last controls whether or not save is 'live', while the
  134.27          # first two further customize behaviour when 'live' save is
  134.28 @@ -84,7 +90,8 @@ def save(fd, dominfo, network, live, dst
  134.29          # libxenguest; see the comments and/or code in xc_linux_save() for
  134.30          # more information.
  134.31          cmd = [xen.util.auxbin.pathTo(XC_SAVE), str(fd),
  134.32 -               str(dominfo.getDomid()), "0", "0", str(int(live) | (int(hvm) << 2)) ]
  134.33 +               str(dominfo.getDomid()), "0", "0", 
  134.34 +               str(int(live) | (int(hvm) << 2) | (int(stdvga) << 3)) ]
  134.35          log.debug("[xc_save]: %s", string.join(cmd))
  134.36  
  134.37          def saveInputHandler(line, tochild):
  134.38 @@ -183,11 +190,11 @@ def restore(xd, fd, dominfo = None, paus
  134.39  
  134.40      # if hvm, pass mem size to calculate the store_mfn
  134.41      image_cfg = dominfo.info.get('image', {})
  134.42 -    is_hvm  = image_cfg.has_key('hvm')
  134.43 +    is_hvm = dominfo.info.is_hvm()
  134.44      if is_hvm:
  134.45          hvm  = dominfo.info['memory_static_min']
  134.46 -        apic = dominfo.info['image']['hvm'].get('apic', 0)
  134.47 -        pae  = dominfo.info['image']['hvm'].get('pae',  0)
  134.48 +        apic = int(dominfo.info['platform'].get('apic', 0))
  134.49 +        pae  = int(dominfo.info['platform'].get('pae',  0))
  134.50          log.info("restore hvm domain %d, mem=%d, apic=%d, pae=%d",
  134.51                   dominfo.domid, hvm, apic, pae)
  134.52      else:
  134.53 @@ -224,6 +231,15 @@ def restore(xd, fd, dominfo = None, paus
  134.54  
  134.55          forkHelper(cmd, fd, handler.handler, True)
  134.56  
  134.57 +        # We don't want to pass this fd to any other children -- we 
  134.58 +        # might need to recover ths disk space that backs it.
  134.59 +        try:
  134.60 +            flags = fcntl.fcntl(fd, fcntl.F_GETFD)
  134.61 +            flags |= fcntl.FD_CLOEXEC
  134.62 +            fcntl.fcntl(fd, fcntl.F_SETFD, flags)
  134.63 +        except:
  134.64 +            pass
  134.65 +
  134.66          if handler.store_mfn is None:
  134.67              raise XendError('Could not read store MFN')
  134.68  
   135.1 --- a/tools/python/xen/xend/XendConfig.py	Wed Mar 21 17:03:00 2007 -0500
   135.2 +++ b/tools/python/xen/xend/XendConfig.py	Wed Mar 21 18:08:31 2007 -0500
   135.3 @@ -12,7 +12,7 @@
   135.4  # License along with this library; if not, write to the Free Software
   135.5  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   135.6  #============================================================================
   135.7 -# Copyright (C) 2006 XenSource Ltd
   135.8 +# Copyright (C) 2006-2007 XenSource Ltd
   135.9  #============================================================================
  135.10  
  135.11  import logging
  135.12 @@ -28,7 +28,7 @@ from xen.xend.PrettyPrint import prettyp
  135.13  from xen.xend.XendConstants import DOM_STATE_HALTED
  135.14  
  135.15  log = logging.getLogger("xend.XendConfig")
  135.16 -log.setLevel(logging.DEBUG)
  135.17 +log.setLevel(logging.WARN)
  135.18  
  135.19  
  135.20  """
  135.21 @@ -105,28 +105,23 @@ XENAPI_CFG_TO_LEGACY_CFG = {
  135.22      'uuid': 'uuid',
  135.23      'vcpus_number': 'vcpus',
  135.24      'cpus': 'cpus',
  135.25 -    'memory_static_min': 'memory',
  135.26 -    'memory_static_max': 'maxmem',
  135.27      'name_label': 'name',
  135.28      'actions_after_shutdown': 'on_poweroff',
  135.29      'actions_after_reboot': 'on_reboot',
  135.30      'actions_after_crash': 'on_crash', 
  135.31 -    'platform_localtime': 'localtime',
  135.32      'PV_bootloader': 'bootloader',
  135.33      'PV_bootloader_args': 'bootloader_args',
  135.34  }
  135.35  
  135.36  LEGACY_CFG_TO_XENAPI_CFG = reverse_dict(XENAPI_CFG_TO_LEGACY_CFG)
  135.37  
  135.38 -# Mapping from XendConfig configuration keys to the old
  135.39 -# legacy configuration keys that are found in the 'image'
  135.40 -# SXP object.
  135.41 -XENAPI_HVM_CFG = {
  135.42 -    'platform_std_vga': 'stdvga',
  135.43 -    'platform_serial' : 'serial',
  135.44 -    'platform_localtime': 'localtime',
  135.45 -    'platform_keymap' : 'keymap'
  135.46 -}    
  135.47 +# Platform configuration keys.
  135.48 +XENAPI_PLATFORM_CFG = [ 'acpi', 'apic', 'boot', 'device_model', 'display', 
  135.49 +                        'fda', 'fdb', 'keymap', 'isa', 'localtime',
  135.50 +                        'nographic', 'pae', 'serial', 'sdl',
  135.51 +                        'soundhw','stdvga', 'usb', 'usbdevice', 'vnc',
  135.52 +                        'vncconsole', 'vncdisplay', 'vnclisten',
  135.53 +                        'vncpasswd', 'vncunused', 'xauthority']
  135.54  
  135.55  # List of XendConfig configuration keys that have no direct equivalent
  135.56  # in the old world.
  135.57 @@ -139,11 +134,10 @@ XENAPI_CFG_TYPES = {
  135.58      'user_version': str,
  135.59      'is_a_template': bool0,
  135.60      'resident_on': str,
  135.61 -    'memory_static_min': int,
  135.62 +    'memory_static_min': int,  # note these are stored in bytes, not KB!
  135.63      'memory_static_max': int,
  135.64      'memory_dynamic_min': int,
  135.65      'memory_dynamic_max': int,
  135.66 -    'memory_actual': int,
  135.67      'cpus': list,
  135.68      'vcpus_policy': str,
  135.69      'vcpus_params': dict,
  135.70 @@ -151,7 +145,6 @@ XENAPI_CFG_TYPES = {
  135.71      'actions_after_shutdown': str,
  135.72      'actions_after_reboot': str,
  135.73      'actions_after_crash': str,
  135.74 -    'tpm_backend': int,    
  135.75      'PV_bootloader': str,
  135.76      'PV_kernel': str,
  135.77      'PV_ramdisk': str,
  135.78 @@ -159,15 +152,10 @@ XENAPI_CFG_TYPES = {
  135.79      'PV_bootloader_args': str,
  135.80      'HVM_boot_policy': str,
  135.81      'HVM_boot_params': dict,
  135.82 -    'platform_std_vga': bool0,
  135.83 -    'platform_serial': str,
  135.84 -    'platform_localtime': bool0,
  135.85 -    'platform_clock_offset': bool0,
  135.86 -    'platform_enable_audio': bool0,
  135.87 -    'platform_keymap': str,
  135.88 -    'pci_bus': str,
  135.89 +    'PCI_bus': str,
  135.90 +    'platform': dict,
  135.91      'tools_version': dict,
  135.92 -    'otherconfig': dict,
  135.93 +    'other_config': dict,
  135.94  }
  135.95  
  135.96  # List of legacy configuration keys that have no equivalent in the
  135.97 @@ -237,44 +225,7 @@ LEGACY_XENSTORE_VM_PARAMS = [
  135.98      'on_xend_stop',
  135.99  ]
 135.100  
 135.101 -LEGACY_IMAGE_CFG = [
 135.102 -    ('root', str),
 135.103 -    ('ip', str),
 135.104 -    ('nographic', int),
 135.105 -    ('vnc', int),
 135.106 -    ('sdl', int),
 135.107 -    ('vncdisplay', int),
 135.108 -    ('vncunused', int),
 135.109 -    ('vncpasswd', str),
 135.110 -    ('vnclisten', str),
 135.111 -]
 135.112 -
 135.113 -LEGACY_IMAGE_HVM_CFG = [
 135.114 -    ('device_model', str),
 135.115 -    ('display', str),
 135.116 -    ('xauthority', str),
 135.117 -    ('vncconsole', int),
 135.118 -    ('pae', int),
 135.119 -    ('apic', int),
 135.120 -]
 135.121 -
 135.122 -LEGACY_IMAGE_HVM_DEVICES_CFG = [
 135.123 -    ('acpi', int),    
 135.124 -    ('boot', str),
 135.125 -    ('fda', str),
 135.126 -    ('fdb', str),
 135.127 -    ('isa', int),
 135.128 -    ('keymap', str),    
 135.129 -    ('localtime', int),    
 135.130 -    ('serial', str),
 135.131 -    ('stdvga', int),
 135.132 -    ('soundhw', str),
 135.133 -    ('usb', int),
 135.134 -    ('usbdevice', str),    
 135.135 -    ('vcpus', int),
 135.136 -]
 135.137 -
 135.138 -LEGACY_DM = '/usr/lib/xen/bin/qemu-dm'
 135.139 +DEFAULT_DM = '/usr/lib/xen/bin/qemu-dm'
 135.140  
 135.141  ##
 135.142  ## Config Choices
 135.143 @@ -316,7 +267,6 @@ class XendConfig(dict):
 135.144              self._sxp_to_xapi_unsupported(sxp_obj)
 135.145          elif xapi:
 135.146              self.update_with_xenapi_config(xapi)
 135.147 -            self._add_xapi_unsupported(xapi)
 135.148          elif dominfo:
 135.149              # output from xc.domain_getinfo
 135.150              self._dominfo_to_xapi(dominfo)
 135.151 @@ -361,9 +311,7 @@ class XendConfig(dict):
 135.152              'shadow_memory': 0,
 135.153              'memory_static_max': 0,
 135.154              'memory_dynamic_max': 0,
 135.155 -            'memory_actual': 0,
 135.156              'devices': {},
 135.157 -            'image': {},
 135.158              'security': None,
 135.159              'on_xend_start': 'ignore',
 135.160              'on_xend_stop': 'ignore',
 135.161 @@ -377,24 +325,44 @@ class XendConfig(dict):
 135.162              'vbd_refs': [],
 135.163              'vtpm_refs': [],
 135.164              'other_config': {},
 135.165 +            'platform': {}
 135.166          }
 135.167          
 135.168          return defaults
 135.169  
 135.170 +    #
 135.171 +    # Here we assume these values exist in the dict.
 135.172 +    # If they don't we have a bigger problem, lets not
 135.173 +    # try and 'fix it up' but acutually fix the cause ;-)
 135.174 +    #
 135.175      def _memory_sanity_check(self):
 135.176 -        if self['memory_static_min'] == 0:
 135.177 -            self['memory_static_min'] = self['memory_dynamic_min']
 135.178 -
 135.179 -        # If the static max is not set, let's set it to dynamic max.
 135.180 -        # If the static max is smaller than static min, then fix it!
 135.181 -        self['memory_static_max'] = max(self['memory_static_max'],
 135.182 -                                        self['memory_dynamic_max'],
 135.183 -                                        self['memory_static_min'])
 135.184 -
 135.185 -        for mem_type in ('memory_static_min', 'memory_static_max'):
 135.186 -            if self[mem_type] <= 0:
 135.187 -                raise XendConfigError('Memory value too low for %s: %d' %
 135.188 -                                      (mem_type, self[mem_type]))
 135.189 +        log.debug("_memory_sanity_check memory_static_min: %s, "
 135.190 +                      "memory_static_max: %i, "
 135.191 +                      "memory_dynamic_min: %i, " 
 135.192 +                      "memory_dynamic_max: %i",
 135.193 +                      self["memory_static_min"],
 135.194 +                      self["memory_static_max"],
 135.195 +                      self["memory_dynamic_min"],
 135.196 +                      self["memory_dynamic_max"])
 135.197 +        
 135.198 +        if not self["memory_static_min"] <= self["memory_static_max"]:
 135.199 +            raise XendConfigError("memory_static_min must be less " \
 135.200 +                                  "than or equal to memory_static_max") 
 135.201 +        if not self["memory_dynamic_min"] <= self["memory_dynamic_max"]:
 135.202 +            raise XendConfigError("memory_dynamic_min must be less " \
 135.203 +                                  "than or equal to memory_dynamic_max")
 135.204 +        if not self["memory_static_min"] <= self["memory_dynamic_min"]:
 135.205 +            raise XendConfigError("memory_static_min must be less " \
 135.206 +                                  "than or equal to memory_dynamic_min")
 135.207 +        if not self["memory_dynamic_max"] <= self["memory_static_max"]:
 135.208 +            raise XendConfigError("memory_dynamic_max must be less " \
 135.209 +                                  "than or equal to memory_static_max")
 135.210 +        if not self["memory_dynamic_max"] > 0:
 135.211 +            raise XendConfigError("memory_dynamic_max must be greater " \
 135.212 +                                  "than zero")
 135.213 +        if not self["memory_static_max"] > 0:
 135.214 +            raise XendConfigError("memory_static_max must be greater " \
 135.215 +                                  "than zero")
 135.216  
 135.217      def _actions_sanity_check(self):
 135.218          for event in ['shutdown', 'reboot', 'crash']:
 135.219 @@ -417,19 +385,34 @@ class XendConfig(dict):
 135.220          if 'name_label' not in self:
 135.221              self['name_label'] = 'Domain-' + self['uuid']
 135.222  
 135.223 +    def _platform_sanity_check(self):
 135.224 +        if self.is_hvm():
 135.225 +            if 'device_model' not in self['platform']:
 135.226 +                self['platform']['device_model'] = DEFAULT_DM
 135.227 +
 135.228 +            # Compatibility hack, can go away soon.
 135.229 +            if 'soundhw' not in self['platform'] and \
 135.230 +               self['platform'].get('enable_audio'):
 135.231 +                self['platform']['soundhw'] = 'sb16'
 135.232 +
 135.233      def validate(self):
 135.234          self._uuid_sanity_check()
 135.235          self._name_sanity_check()
 135.236          self._memory_sanity_check()
 135.237          self._actions_sanity_check()
 135.238          self._vcpus_sanity_check()
 135.239 +        self._platform_sanity_check()
 135.240  
 135.241      def _dominfo_to_xapi(self, dominfo):
 135.242          self['domid'] = dominfo['domid']
 135.243          self['online_vcpus'] = dominfo['online_vcpus']
 135.244          self['vcpus_number'] = dominfo['max_vcpu_id'] + 1
 135.245 -        self['memory_dynamic_min'] = (dominfo['mem_kb'] + 1023)/1024
 135.246 -        self['memory_dynamic_max'] = (dominfo['maxmem_kb'] + 1023)/1024
 135.247 +
 135.248 +        self['memory_dynamic_min'] = dominfo['mem_kb'] * 1024
 135.249 +        self['memory_dynamic_max'] = dominfo['mem_kb'] * 1024
 135.250 +        self['memory_static_min'] = 0
 135.251 +        self['memory_static_max'] = dominfo['maxmem_kb'] * 1024
 135.252 +
 135.253          self['cpu_time'] = dominfo['cpu_time']/1e9
 135.254          # TODO: i don't know what the security stuff expects here
 135.255          if dominfo.get('ssidref'):
 135.256 @@ -483,6 +466,13 @@ class XendConfig(dict):
 135.257                  log.warn('Ignoring unrecognised value for deprecated option:'
 135.258                           'restart = \'%s\'', restart)
 135.259  
 135.260 +        # Handle memory, passed in as MiB
 135.261 +
 135.262 +        if sxp.child_value(sxp_cfg, "memory") != None:
 135.263 +            cfg["memory"] = int(sxp.child_value(sxp_cfg, "memory"))
 135.264 +        if sxp.child_value(sxp_cfg, "maxmem") != None:
 135.265 +            cfg["maxmem"] = int(sxp.child_value(sxp_cfg, "maxmem"))
 135.266 +            
 135.267          # Only extract options we know about.
 135.268          extract_keys = LEGACY_UNSUPPORTED_BY_XENAPI_CFG
 135.269          extract_keys += XENAPI_CFG_TO_LEGACY_CFG.values()
 135.270 @@ -498,6 +488,18 @@ class XendConfig(dict):
 135.271                      log.warn("Unable to parse key %s: %s: %s" %
 135.272                               (key, str(val), e))
 135.273  
 135.274 +        if 'platform' not in cfg:
 135.275 +            cfg['platform'] = {}
 135.276 +        localtime = sxp.child_value(sxp_cfg, 'localtime')
 135.277 +        if localtime is not None:
 135.278 +            cfg['platform']['localtime'] = localtime
 135.279 +
 135.280 +        # Compatibility hack -- can go soon.
 135.281 +        for key in XENAPI_PLATFORM_CFG:
 135.282 +            val = sxp.child_value(sxp_cfg, "platform_" + key, None)
 135.283 +            if val is not None:
 135.284 +                self['platform'][key] = val
 135.285 +
 135.286          # Compatibility hack -- can go soon.
 135.287          boot_order = sxp.child_value(sxp_cfg, 'HVM_boot')
 135.288          if boot_order:
 135.289 @@ -640,6 +642,21 @@ class XendConfig(dict):
 135.290              except KeyError:
 135.291                  pass
 135.292  
 135.293 +        # Lets try and handle memory correctly
 135.294 +
 135.295 +        MiB = 1024 * 1024
 135.296 +
 135.297 +        if "memory" in cfg:
 135.298 +            self["memory_static_min"] = 0
 135.299 +            self["memory_static_max"] = int(cfg["memory"]) * MiB
 135.300 +            self["memory_dynamic_min"] = int(cfg["memory"]) * MiB
 135.301 +            self["memory_dynamic_max"] = int(cfg["memory"]) * MiB
 135.302 +            
 135.303 +            if "maxmem" in cfg:
 135.304 +                self["memory_static_max"] = int(cfg["maxmem"]) * MiB
 135.305 +
 135.306 +        self._memory_sanity_check()
 135.307 +
 135.308          def update_with(n, o):
 135.309              if not self.get(n):
 135.310                  self[n] = cfg.get(o, '')
 135.311 @@ -652,17 +669,9 @@ class XendConfig(dict):
 135.312              self.update_with_image_sxp(image_sxp)
 135.313  
 135.314          # Convert Legacy HVM parameters to Xen API configuration
 135.315 -        self['platform_std_vga'] = bool0(cfg.get('stdvga', 0))
 135.316 -        self['platform_serial'] = str(cfg.get('serial', ''))
 135.317 -        self['platform_localtime'] = bool0(cfg.get('localtime', 0))
 135.318 -        self['platform_enable_audio'] = bool0(cfg.get('soundhw', 0))
 135.319 -
 135.320 -        # make sure a sane maximum is set
 135.321 -        if self['memory_static_max'] <= 0:
 135.322 -            self['memory_static_max'] = self['memory_static_min']
 135.323 -            
 135.324 -        self['memory_dynamic_max'] = self['memory_static_max']
 135.325 -        self['memory_dynamic_min'] = self['memory_static_min']
 135.326 +        for key in XENAPI_PLATFORM_CFG:
 135.327 +            if key in cfg:
 135.328 +                self['platform'][key] = cfg[key]
 135.329  
 135.330          # set device references in the configuration
 135.331          self['devices'] = cfg.get('devices', {})
 135.332 @@ -672,7 +681,7 @@ class XendConfig(dict):
 135.333          self['vtpm_refs'] = cfg.get('vtpm_refs', [])
 135.334  
 135.335          # coalesce hvm vnc frame buffer with vfb config
 135.336 -        if self['image']['type'] == 'hvm' and self['image'].get('vnc', 0):
 135.337 +        if self.is_hvm() and self['platform'].get('vnc', 0):
 135.338              # add vfb device if it isn't there already
 135.339              has_rfb = False
 135.340              for console_uuid in self['console_refs']:
 135.341 @@ -685,11 +694,11 @@ class XendConfig(dict):
 135.342  
 135.343              if not has_rfb:
 135.344                  dev_config = ['vfb']
 135.345 -                # copy VNC related params from image config to vfb dev conf
 135.346 +                # copy VNC related params from platform config to vfb dev conf
 135.347                  for key in ['vncpasswd', 'vncunused', 'vncdisplay',
 135.348                              'vnclisten']:
 135.349 -                    if key in self['image']:
 135.350 -                        dev_config.append([key, self['image'][key]])
 135.351 +                    if key in self['platform']:
 135.352 +                        dev_config.append([key, self['platform'][key]])
 135.353  
 135.354                  self.device_add('vfb', cfg_sxp = dev_config)
 135.355  
 135.356 @@ -706,39 +715,19 @@ class XendConfig(dict):
 135.357          # the image (as well as HVM images)
 135.358          image_sxp = sxp.child_value(sxp_cfg, 'image', [])
 135.359          if image_sxp:
 135.360 -            image = {}
 135.361 -            image['type'] = sxp.name(image_sxp)
 135.362 -            for arg, conv in LEGACY_IMAGE_CFG:
 135.363 -                val = sxp.child_value(image_sxp, arg, None)
 135.364 -                if val != None:
 135.365 -                    image[arg] = conv(val)
 135.366 -
 135.367 -            image_hvm = {}
 135.368 -            for arg, conv in LEGACY_IMAGE_HVM_CFG:
 135.369 -                val = sxp.child_value(image_sxp, arg, None)
 135.370 -                if val != None:
 135.371 -                    image_hvm[arg] = conv(val)
 135.372 -                    
 135.373 -            image_hvm_devices = {}
 135.374 -            for arg, conv in LEGACY_IMAGE_HVM_DEVICES_CFG:
 135.375 -                val = sxp.child_value(image_sxp, arg, None)
 135.376 -                if val != None:
 135.377 -                    image_hvm_devices[arg] = conv(val)
 135.378 -
 135.379 -            if image_hvm or image_hvm_devices:
 135.380 -                image['hvm'] = image_hvm
 135.381 -                image['hvm']['devices'] = image_hvm_devices
 135.382 -
 135.383 +            image_type = sxp.name(image_sxp)
 135.384 +            if image_type != 'hvm' and image_type != 'linux':
 135.385 +                self['platform']['image_type'] = image_type
 135.386 +            
 135.387 +            for key in XENAPI_PLATFORM_CFG:
 135.388 +                val = sxp.child_value(image_sxp, key, None)
 135.389 +                if val is not None:
 135.390 +                    self['platform'][key] = val
 135.391 +            
 135.392              notes = sxp.children(image_sxp, 'notes')
 135.393              if notes:
 135.394 -                image['notes'] = self.notes_from_sxp(notes[0])
 135.395 -
 135.396 -            self['image'] = image
 135.397 +                self['notes'] = self.notes_from_sxp(notes[0])
 135.398  
 135.399 -            for apikey, imgkey in XENAPI_HVM_CFG.items():
 135.400 -                val = sxp.child_value(image_sxp, imgkey, None)
 135.401 -                if val != None:
 135.402 -                    self[apikey] = val
 135.403              self._hvm_boot_params_from_sxp(image_sxp)
 135.404  
 135.405          # extract backend value
 135.406 @@ -774,33 +763,6 @@ class XendConfig(dict):
 135.407          _set_cfg_if_exists('up_time')
 135.408          _set_cfg_if_exists('status') # TODO, deprecated  
 135.409  
 135.410 -    def _add_xapi_unsupported(self, xapi_dict):
 135.411 -        """Updates the configuration object with entries that are not
 135.412 -        officially supported by the Xen API but is required for
 135.413 -        the rest of Xend to function.
 135.414 -        """
 135.415 -
 135.416 -        # populate image
 135.417 -        if 'image' in xapi_dict:
 135.418 -            self['image'].update(xapi_dict['image'])
 135.419 -        else:
 135.420 -            hvm = self['HVM_boot_policy'] != ''
 135.421 -            self['image']['type'] = hvm and 'hvm' or 'linux'
 135.422 -            if hvm:
 135.423 -                self['image']['hvm'] = {'devices': {}}
 135.424 -                for xapi, cfgapi in XENAPI_HVM_CFG.items():
 135.425 -                    if xapi in self:
 135.426 -                        self['image']['hvm']['devices'][cfgapi] = self[xapi]
 135.427 -
 135.428 -                # currently unsupported options
 135.429 -                self['image']['hvm']['device_model'] = LEGACY_DM
 135.430 -                self['image']['vnc'] = 0
 135.431 -                self['image']['hvm']['pae'] = 1
 135.432 -
 135.433 -                if self['platform_enable_audio']:
 135.434 -                    self['image']['hvm']['devices']['soundhw'] = 'sb16'
 135.435 -
 135.436 -
 135.437      def _get_old_state_string(self):
 135.438          """Returns the old xm state string.
 135.439          @rtype: string
 135.440 @@ -884,18 +846,29 @@ class XendConfig(dict):
 135.441                  else:
 135.442                      sxpr.append([legacy, self[xenapi]])
 135.443  
 135.444 +        MiB = 1024*1024
 135.445 +
 135.446 +        sxpr.append(["maxmem", int(self["memory_static_max"])/MiB])
 135.447 +        sxpr.append(["memory", int(self["memory_dynamic_max"])/MiB])
 135.448 +
 135.449 +        if not legacy_only:
 135.450 +            sxpr.append(['memory_dynamic_min',
 135.451 +                     int(self.get('memory_dynamic_min'))])
 135.452 +            sxpr.append(['memory_dynamic_max',
 135.453 +                     int(self.get('memory_dynamic_max'))])
 135.454 +            sxpr.append(['memory_static_max',
 135.455 +                     int(self.get('memory_static_max'))])
 135.456 +            sxpr.append(['memory_static_min',
 135.457 +                     int(self.get('memory_static_min'))])
 135.458 +
 135.459          for legacy in LEGACY_UNSUPPORTED_BY_XENAPI_CFG:
 135.460              if legacy in ('domid', 'uuid'): # skip these
 135.461                  continue
 135.462              if self.has_key(legacy) and self[legacy] not in (None, []):
 135.463                  sxpr.append([legacy, self[legacy]])
 135.464  
 135.465 -        if 'image' in self and self['image']:
 135.466 -            sxpr.append(['image', self.image_sxpr()])
 135.467 -
 135.468 +        sxpr.append(['image', self.image_sxpr()])
 135.469          sxpr.append(['status', domain.state])
 135.470 -        sxpr.append(['memory_dynamic_min',  self.get('memory_dynamic_min')])
 135.471 -        sxpr.append(['memory_dynamic_max',  self.get('memory_dynamic_max')])
 135.472  
 135.473          if domain.getDomid() is not None:
 135.474              sxpr.append(['state', self._get_old_state_string()])
 135.475 @@ -1339,7 +1312,7 @@ class XendConfig(dict):
 135.476      def image_sxpr(self):
 135.477          """Returns a backwards compatible image SXP expression that is
 135.478          used in xenstore's /vm/<uuid>/image value and xm list."""
 135.479 -        image = [self['image'].get('type', 'linux')]
 135.480 +        image = [self.image_type()]
 135.481          if self.has_key('PV_kernel'):
 135.482              image.append(['kernel', self['PV_kernel']])
 135.483          if self.has_key('PV_ramdisk') and self['PV_ramdisk']:
 135.484 @@ -1347,28 +1320,12 @@ class XendConfig(dict):
 135.485          if self.has_key('PV_args') and self['PV_args']:
 135.486              image.append(['args', self['PV_args']])
 135.487  
 135.488 -        for arg, conv in LEGACY_IMAGE_CFG:
 135.489 -            if self['image'].has_key(arg):
 135.490 -                image.append([arg, self['image'][arg]])
 135.491 -
 135.492 -        if 'hvm' in self['image']:
 135.493 -            for arg, conv in LEGACY_IMAGE_HVM_CFG:
 135.494 -                if self['image']['hvm'].get(arg):
 135.495 -                    image.append([arg, conv(self['image']['hvm'][arg])])
 135.496 +        for key in XENAPI_PLATFORM_CFG:
 135.497 +            if key in self['platform']:
 135.498 +                image.append([key, self['platform'][key]])
 135.499  
 135.500 -        if 'hvm' in self['image'] and 'devices' in self['image']['hvm']:
 135.501 -            for arg, conv in LEGACY_IMAGE_HVM_DEVICES_CFG:
 135.502 -                val = self['image']['hvm']['devices'].get(arg)
 135.503 -                if val != None:
 135.504 -                    try:
 135.505 -                        if conv: val = conv(val)
 135.506 -                    except (ValueError, TypeError):
 135.507 -                        if type(val) == bool: val = int(val)
 135.508 -                            
 135.509 -                    image.append([arg, val])
 135.510 -
 135.511 -        if 'notes' in self['image']:
 135.512 -            image.append(self.notes_sxp(self['image']['notes']))
 135.513 +        if 'notes' in self:
 135.514 +            image.append(self.notes_sxp(self['notes']))
 135.515  
 135.516          return image
 135.517  
 135.518 @@ -1399,57 +1356,24 @@ class XendConfig(dict):
 135.519              self['PV_ramdisk'] = sxp.child_value(image_sxp, 'ramdisk','')
 135.520              self['PV_args'] = kernel_args
 135.521  
 135.522 -        # Store image SXP in python dictionary format
 135.523 -        image = {}
 135.524 -        image['type'] = sxp.name(image_sxp)
 135.525 -        for arg, conv in LEGACY_IMAGE_CFG:
 135.526 -            val = sxp.child_value(image_sxp, arg, None)
 135.527 -            if val != None:
 135.528 -                image[arg] = conv(val)
 135.529 -
 135.530 -        image_hvm = {}
 135.531 -        for arg, conv in LEGACY_IMAGE_HVM_CFG:
 135.532 -            val = sxp.child_value(image_sxp, arg, None)
 135.533 -            if val != None:
 135.534 -                image_hvm[arg] = conv(val)
 135.535 -                    
 135.536 -        image_hvm_devices = {}
 135.537 -        for arg, conv in LEGACY_IMAGE_HVM_DEVICES_CFG:
 135.538 -            val = sxp.child_value(image_sxp, arg, None)
 135.539 -            if val != None:
 135.540 -                try:
 135.541 -                    image_hvm_devices[arg] = conv(val)
 135.542 -                except (ValueError, TypeError):
 135.543 -                    image_hvm_devices[arg] = val
 135.544 -                        
 135.545 -
 135.546 -        if image_hvm or image_hvm_devices:
 135.547 -            image['hvm'] = image_hvm
 135.548 -            image['hvm']['devices'] = image_hvm_devices
 135.549 +        for key in XENAPI_PLATFORM_CFG:
 135.550 +            val = sxp.child_value(image_sxp, key, None)
 135.551 +            if val is not None:
 135.552 +                self['platform'][key] = val
 135.553  
 135.554          notes = sxp.children(image_sxp, 'notes')
 135.555          if notes:
 135.556 -            image['notes'] = self.notes_from_sxp(notes[0])
 135.557 -
 135.558 -        self['image'] = image
 135.559 +            self['notes'] = self.notes_from_sxp(notes[0])
 135.560  
 135.561 -        for apikey, imgkey in XENAPI_HVM_CFG.items():
 135.562 -            val = sxp.child_value(image_sxp, imgkey, None)
 135.563 -            if val != None:
 135.564 -                type_conv = XENAPI_CFG_TYPES[apikey]
 135.565 -                if callable(type_conv):
 135.566 -                    self[apikey] = type_conv(val)
 135.567 -                else:
 135.568 -                    self[apikey] = val
 135.569          self._hvm_boot_params_from_sxp(image_sxp)
 135.570  
 135.571      def set_notes(self, notes):
 135.572          'Add parsed elfnotes to image'
 135.573 -        self['image']['notes'] = notes
 135.574 +        self['notes'] = notes
 135.575  
 135.576      def get_notes(self):
 135.577          try:
 135.578 -            return self['image']['notes'] or {}
 135.579 +            return self['notes'] or {}
 135.580          except KeyError:
 135.581              return {}
 135.582  
 135.583 @@ -1471,11 +1395,9 @@ class XendConfig(dict):
 135.584              self['HVM_boot_policy'] = 'BIOS order'
 135.585              self['HVM_boot_params'] = { 'order' : boot }
 135.586  
 135.587 +    def is_hvm(self):
 135.588 +        return self['HVM_boot_policy'] != ''
 135.589  
 135.590 -#
 135.591 -# debugging 
 135.592 -#
 135.593 -
 135.594 -if __name__ == "__main__":
 135.595 -    pass
 135.596 -    
 135.597 +    def image_type(self):
 135.598 +        stored_type = self['platform'].get('image_type')
 135.599 +        return stored_type or (self.is_hvm() and 'hvm' or 'linux')
   136.1 --- a/tools/python/xen/xend/XendDomain.py	Wed Mar 21 17:03:00 2007 -0500
   136.2 +++ b/tools/python/xen/xend/XendDomain.py	Wed Mar 21 18:08:31 2007 -0500
   136.3 @@ -495,7 +495,7 @@ class XendDomain:
   136.4              self._refresh(refresh_shutdown = False)
   136.5              dom = self.domain_lookup_nr(domid)
   136.6              if not dom:
   136.7 -                raise XendInvalidDomain("No domain named '%s'." % str(domid))
   136.8 +                raise XendInvalidDomain(str(domid))
   136.9              return dom
  136.10          finally:
  136.11              self.domains_lock.release()
  136.12 @@ -674,7 +674,7 @@ class XendDomain:
  136.13                  else:
  136.14                      return domid
  136.15              
  136.16 -            raise XendInvalidDomain("Domain does not exist")
  136.17 +            raise XendInvalidDomain(vm_uuid)
  136.18          finally:
  136.19              self.domains_lock.release()
  136.20          
   137.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Wed Mar 21 17:03:00 2007 -0500
   137.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Wed Mar 21 18:08:31 2007 -0500
   137.3 @@ -13,7 +13,7 @@
   137.4  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   137.5  #============================================================================
   137.6  # Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
   137.7 -# Copyright (C) 2005, 2006 XenSource Ltd
   137.8 +# Copyright (C) 2005-2007 XenSource Ltd
   137.9  #============================================================================
  137.10  
  137.11  """Representation of a single domain.
  137.12 @@ -34,7 +34,7 @@ from types import StringTypes
  137.13  
  137.14  import xen.lowlevel.xc
  137.15  from xen.util import asserts
  137.16 -from xen.util.blkif import blkdev_uname_to_file
  137.17 +from xen.util.blkif import blkdev_uname_to_file, blkdev_uname_to_taptype
  137.18  from xen.util import security
  137.19  
  137.20  from xen.xend import balloon, sxp, uuid, image, arch, osdep
  137.21 @@ -51,6 +51,8 @@ from xen.xend.xenstore.xswatch import xs
  137.22  from xen.xend.XendConstants import *
  137.23  from xen.xend.XendAPIConstants import *
  137.24  
  137.25 +from xen.xend.XendVMMetrics import XendVMMetrics
  137.26 +
  137.27  MIGRATE_TIMEOUT = 30.0
  137.28  BOOTLOADER_LOOPBACK_DEVICE = '/dev/xvdp'
  137.29  
  137.30 @@ -176,14 +178,8 @@ def recreate(info, priv):
  137.31          vm._storeVmDetails()
  137.32          vm._storeDomDetails()
  137.33          
  137.34 -    if vm.info['image']: # Only dom0 should be without an image entry when
  137.35 -                         # recreating, but we cope with missing ones
  137.36 -                         # elsewhere just in case.
  137.37 -        vm.image = image.create(vm,
  137.38 -                                vm.info,
  137.39 -                                vm.info['image'],
  137.40 -                                vm.info['devices'])
  137.41 -        vm.image.recreate()
  137.42 +    vm.image = image.create(vm, vm.info)
  137.43 +    vm.image.recreate()
  137.44  
  137.45      vm._registerWatches()
  137.46      vm.refreshShutdown(xeninfo)
  137.47 @@ -375,6 +371,8 @@ class XendDomainInfo:
  137.48              self._augmentInfo(priv)
  137.49  
  137.50          self._checkName(self.info['name_label'])
  137.51 +
  137.52 +        self.metrics = XendVMMetrics(uuid.createString(), self)
  137.53              
  137.54  
  137.55      #
  137.56 @@ -448,9 +446,7 @@ class XendDomainInfo:
  137.57          self.storeDom("control/shutdown", reason)
  137.58  
  137.59          ## shutdown hypercall for hvm domain desides xenstore write
  137.60 -        image_cfg = self.info.get('image', {})
  137.61 -        hvm = image_cfg.has_key('hvm')
  137.62 -        if hvm:
  137.63 +        if self.info.is_hvm():
  137.64              for code in DOMAIN_SHUTDOWN_REASONS.keys():
  137.65                  if DOMAIN_SHUTDOWN_REASONS[code] == reason:
  137.66                      break
  137.67 @@ -580,12 +576,14 @@ class XendDomainInfo:
  137.68          if target <= 0:
  137.69              raise XendError('Invalid memory size')
  137.70          
  137.71 -        self.info['memory_static_min'] = target
  137.72 +        MiB = 1024 * 1024
  137.73 +        self.info['memory_dynamic_min'] = target * MiB
  137.74 +        self.info['memory_dynamic_max'] = target * MiB
  137.75 +
  137.76          if self.domid >= 0:
  137.77              self.storeVm("memory", target)
  137.78              self.storeDom("memory/target", target << 10)
  137.79          else:
  137.80 -            self.info['memory_dynamic_min'] = target
  137.81              xen.xend.XendDomain.instance().managed_config_save(self)
  137.82  
  137.83      def setMemoryMaximum(self, limit):
  137.84 @@ -635,6 +633,10 @@ class XendDomainInfo:
  137.85          except RuntimeError, exn:
  137.86              raise XendError(str(exn))
  137.87  
  137.88 +
  137.89 +    def getDomInfo(self):
  137.90 +        return dom_get(self.domid)
  137.91 +
  137.92      #
  137.93      # internal functions ... TODO: re-categorised
  137.94      # 
  137.95 @@ -664,6 +666,10 @@ class XendDomainInfo:
  137.96                  if arg in XendConfig.LEGACY_CFG_TO_XENAPI_CFG:
  137.97                      xapiarg = XendConfig.LEGACY_CFG_TO_XENAPI_CFG[arg]
  137.98                      self.info[xapiarg] = val
  137.99 +                elif arg == "memory":
 137.100 +                    self.info["static_memory_min"] = val
 137.101 +                elif arg == "maxmem":
 137.102 +                    self.info["static_memory_max"] = val
 137.103                  else:
 137.104                      self.info[arg] = val
 137.105  
 137.106 @@ -780,7 +786,7 @@ class XendDomainInfo:
 137.107              'vm':                 self.vmpath,
 137.108              'name':               self.info['name_label'],
 137.109              'console/limit':      str(xoptions.get_console_limit() * 1024),
 137.110 -            'memory/target':      str(self.info['memory_static_min'] * 1024),
 137.111 +            'memory/target':      str(self.info['memory_dynamic_max'] / 1024),
 137.112              }
 137.113  
 137.114          def f(n, v):
 137.115 @@ -864,7 +870,15 @@ class XendDomainInfo:
 137.116                  xapiarg = XendConfig.LEGACY_CFG_TO_XENAPI_CFG[arg]
 137.117                  if val != None and val != self.info[xapiarg]:
 137.118                      self.info[xapiarg] = val
 137.119 -                    changed= True
 137.120 +                    changed = True
 137.121 +            elif arg == "memory":
 137.122 +                if val != None and val != self.info["static_memory_min"]:
 137.123 +                    self.info["static_memory_min"] = val
 137.124 +                    changed = True
 137.125 +            elif arg == "maxmem":
 137.126 +                if val != None and val != self.info["static_memory_max"]:
 137.127 +                    self.info["static_memory_max"] = val
 137.128 +                    changed = True
 137.129  
 137.130          # Check whether image definition has been updated
 137.131          image_sxp = self._readVm('image')
 137.132 @@ -969,11 +983,12 @@ class XendDomainInfo:
 137.133  
 137.134      def getMemoryTarget(self):
 137.135          """Get this domain's target memory size, in KB."""
 137.136 -        return self.info['memory_static_min'] * 1024
 137.137 +        return self.info['memory_dynamic_max'] / 1024
 137.138  
 137.139      def getMemoryMaximum(self):
 137.140          """Get this domain's maximum memory size, in KB."""
 137.141 -        return self.info['memory_static_max'] * 1024
 137.142 +        # remember, info now stores memory in bytes
 137.143 +        return self.info['memory_static_max'] / 1024
 137.144  
 137.145      def getResume(self):
 137.146          return str(self._resume)
 137.147 @@ -1389,9 +1404,7 @@ class XendDomainInfo:
 137.148  
 137.149          self.shutdownStartTime = None
 137.150  
 137.151 -        image_cfg = self.info.get('image', {})
 137.152 -        hvm = image_cfg.has_key('hvm')
 137.153 -
 137.154 +        hvm = self.info.is_hvm()
 137.155          if hvm:
 137.156              info = xc.xeninfo()
 137.157              if 'hvm' not in info['xen_caps']:
 137.158 @@ -1438,14 +1451,8 @@ class XendDomainInfo:
 137.159  
 137.160          self._configureBootloader()
 137.161  
 137.162 -        if not self._infoIsSet('image'):
 137.163 -            raise VmError('Missing image in configuration')
 137.164 -
 137.165          try:
 137.166 -            self.image = image.create(self,
 137.167 -                                      self.info,
 137.168 -                                      self.info['image'],
 137.169 -                                      self.info['devices'])
 137.170 +            self.image = image.create(self, self.info)
 137.171  
 137.172              localtime = self.info.get('platform_localtime', False)
 137.173              if localtime:
 137.174 @@ -1463,13 +1470,14 @@ class XendDomainInfo:
 137.175              # Use architecture- and image-specific calculations to determine
 137.176              # the various headrooms necessary, given the raw configured
 137.177              # values. maxmem, memory, and shadow are all in KiB.
 137.178 +            # but memory_static_max etc are all stored in bytes now.
 137.179              memory = self.image.getRequiredAvailableMemory(
 137.180 -                self.info['memory_static_min'] * 1024)
 137.181 +                self.info['memory_dynamic_max'] / 1024)
 137.182              maxmem = self.image.getRequiredAvailableMemory(
 137.183 -                self.info['memory_static_max'] * 1024)
 137.184 +                self.info['memory_static_max'] / 1024)
 137.185              shadow = self.image.getRequiredShadowMemory(
 137.186 -                self.info['shadow_memory'] * 1024,
 137.187 -                self.info['memory_static_max'] * 1024)
 137.188 +                self.info['shadow_memory'] / 1024,
 137.189 +                self.info['memory_static_max'] / 1024)
 137.190  
 137.191              log.debug("_initDomain:shadow_memory=0x%x, memory_static_max=0x%x, memory_static_min=0x%x.", self.info['shadow_memory'], self.info['memory_static_max'], self.info['memory_static_min'],)
 137.192              # Round shadow up to a multiple of a MiB, as shadow_mem_control
 137.193 @@ -1505,9 +1513,15 @@ class XendDomainInfo:
 137.194              self.info['start_time'] = time.time()
 137.195  
 137.196              self._stateSet(DOM_STATE_RUNNING)
 137.197 -        except (RuntimeError, VmError), exn:
 137.198 +        except VmError, exn:
 137.199              log.exception("XendDomainInfo.initDomain: exception occurred")
 137.200 -            self.image.cleanupBootloading()
 137.201 +            if self.image:
 137.202 +                self.image.cleanupBootloading()
 137.203 +            raise exn
 137.204 +        except RuntimeError, exn:
 137.205 +            log.exception("XendDomainInfo.initDomain: exception occurred")
 137.206 +            if self.image:
 137.207 +                self.image.cleanupBootloading()
 137.208              raise VmError(str(exn))
 137.209  
 137.210  
 137.211 @@ -1574,13 +1588,8 @@ class XendDomainInfo:
 137.212          self.console_mfn = console_mfn
 137.213  
 137.214          self._introduceDomain()
 137.215 -        image_cfg = self.info.get('image', {})
 137.216 -        hvm = image_cfg.has_key('hvm')
 137.217 -        if hvm:
 137.218 -            self.image = image.create(self,
 137.219 -                    self.info,
 137.220 -                    self.info['image'],
 137.221 -                    self.info['devices'])
 137.222 +        if self.info.is_hvm():
 137.223 +            self.image = image.create(self, self.info)
 137.224              if self.image:
 137.225                  self.image.createDeviceModel(True)
 137.226                  self.image.register_shutdown_watch()
 137.227 @@ -1657,7 +1666,18 @@ class XendDomainInfo:
 137.228              log.exception("XendDomainInfo.destroy: xc.domain_destroy failed.")
 137.229  
 137.230          from xen.xend import XendDomain
 137.231 -        XendDomain.instance().remove_domain(self)
 137.232 +
 137.233 +        if "transient" in self.info["other_config"]\
 137.234 +           and bool(self.info["other_config"]["transient"]):
 137.235 +            xendDomainInstance = XendDomain.instance()
 137.236 +            
 137.237 +            xendDomainInstance.domains_lock.acquire()
 137.238 +            xendDomainInstance._refresh(refresh_shutdown = False)
 137.239 +            xendDomainInstance.domains_lock.release()
 137.240 +            
 137.241 +            xendDomainInstance.domain_delete(self.info["name_label"])
 137.242 +        else:
 137.243 +            XendDomain.instance().remove_domain(self)
 137.244  
 137.245          self.cleanupDomain()
 137.246          self._cleanup_phantom_devs(paths)
 137.247 @@ -1742,11 +1762,7 @@ class XendDomainInfo:
 137.248  
 137.249          if boot:
 137.250              # HVM booting.
 137.251 -            self.info['image']['type'] = 'hvm'
 137.252 -            if not 'devices' in self.info['image']:
 137.253 -                self.info['image']['devices'] = {}
 137.254 -            self.info['image']['devices']['boot'] = \
 137.255 -                self.info['HVM_boot_params'].get('order', 'dc')
 137.256 +            pass
 137.257          elif not blexec and kernel:
 137.258              # Boot from dom0.  Nothing left to do -- the kernel and ramdisk
 137.259              # will be picked up by image.py.
 137.260 @@ -1770,7 +1786,8 @@ class XendDomainInfo:
 137.261              disk = devinfo[1]['uname']
 137.262  
 137.263              fn = blkdev_uname_to_file(disk)
 137.264 -            mounted = devtype == 'tap' and not os.stat(fn).st_rdev
 137.265 +            taptype = blkdev_uname_to_taptype(disk)
 137.266 +            mounted = devtype == 'tap' and taptype != 'aio' and taptype != 'sync' and not os.stat(fn).st_rdev
 137.267              if mounted:
 137.268                  # This is a file, not a device.  pygrub can cope with a
 137.269                  # file if it's raw, but if it's QCOW or other such formats
 137.270 @@ -1786,7 +1803,7 @@ class XendDomainInfo:
 137.271  
 137.272                  from xen.xend import XendDomain
 137.273                  dom0 = XendDomain.instance().privilegedDomain()
 137.274 -                dom0._waitForDeviceUUID(dom0.create_vbd(vbd, fn))
 137.275 +                dom0._waitForDeviceUUID(dom0.create_vbd(vbd, disk))
 137.276                  fn = BOOTLOADER_LOOPBACK_DEVICE
 137.277  
 137.278              try:
 137.279 @@ -1844,7 +1861,7 @@ class XendDomainInfo:
 137.280              # 1MB per vcpu plus 4Kib/Mib of RAM.  This is higher than 
 137.281              # the minimum that Xen would allocate if no value were given.
 137.282              overhead_kb = self.info['vcpus_number'] * 1024 + \
 137.283 -                          self.info['memory_static_max'] * 4
 137.284 +                          (self.info['memory_static_max'] / 1024 / 1024) * 4
 137.285              overhead_kb = ((overhead_kb + 1023) / 1024) * 1024
 137.286              # The domain might already have some shadow memory
 137.287              overhead_kb -= xc.shadow_mem_control(self.domid) * 1024
 137.288 @@ -1910,10 +1927,14 @@ class XendDomainInfo:
 137.289              if self._infoIsSet(info_key):
 137.290                  to_store[key] = str(self.info[info_key])
 137.291  
 137.292 -        if self.info.get('image'):
 137.293 -            image_sxpr = self.info.image_sxpr()
 137.294 -            if image_sxpr:
 137.295 -                to_store['image'] = sxp.to_string(image_sxpr)
 137.296 +        if self._infoIsSet("static_memory_min"):
 137.297 +            to_store["memory"] = str(self.info["static_memory_min"])
 137.298 +        if self._infoIsSet("static_memory_max"):
 137.299 +            to_store["maxmem"] = str(self.info["static_memory_max"])
 137.300 +
 137.301 +        image_sxpr = self.info.image_sxpr()
 137.302 +        if image_sxpr:
 137.303 +            to_store['image'] = sxp.to_string(image_sxpr)
 137.304  
 137.305          if self._infoIsSet('security'):
 137.306              secinfo = self.info['security']
 137.307 @@ -2000,7 +2021,11 @@ class XendDomainInfo:
 137.308              info = dom_get(self.domid)
 137.309              if not info:
 137.310                  return
 137.311 -            
 137.312 +
 137.313 +        if info["maxmem_kb"] < 0:
 137.314 +            info["maxmem_kb"] = XendNode.instance() \
 137.315 +                                .physinfo_dict()['total_memory'] * 1024
 137.316 +
 137.317          #manually update ssidref / security fields
 137.318          if security.on() and info.has_key('ssidref'):
 137.319              if (info['ssidref'] != 0) and self.info.has_key('security'):
 137.320 @@ -2057,15 +2082,6 @@ class XendDomainInfo:
 137.321          return self.info.get('memory_dynamic_max', 0)
 137.322      def get_memory_dynamic_min(self):
 137.323          return self.info.get('memory_dynamic_min', 0)
 137.324 -
 137.325 -    def get_vcpus_policy(self):
 137.326 -        sched_id = xc.sched_id_get()
 137.327 -        if sched_id == xen.lowlevel.xc.XEN_SCHEDULER_SEDF:
 137.328 -            return 'sedf'
 137.329 -        elif sched_id == xen.lowlevel.xc.XEN_SCHEDULER_CREDIT:
 137.330 -            return 'credit'
 137.331 -        else:
 137.332 -            return 'unknown'
 137.333      def get_vcpus_params(self):
 137.334          if self.getDomid() is None:
 137.335              return self.info['vcpus_params']
 137.336 @@ -2074,22 +2090,14 @@ class XendDomainInfo:
 137.337          return retval
 137.338      def get_power_state(self):
 137.339          return XEN_API_VM_POWER_STATE[self.state]
 137.340 -    def get_platform_std_vga(self):
 137.341 -        return self.info.get('platform_std_vga', False)    
 137.342 -    def get_platform_serial(self):
 137.343 -        return self.info.get('platform_serial', '')
 137.344 -    def get_platform_localtime(self):
 137.345 -        return self.info.get('platform_localtime', False)
 137.346 -    def get_platform_clock_offset(self):
 137.347 -        return self.info.get('platform_clock_offset', False)
 137.348 -    def get_platform_enable_audio(self):
 137.349 -        return self.info.get('platform_enable_audio', False)
 137.350 -    def get_platform_keymap(self):
 137.351 -        return self.info.get('platform_keymap', '')
 137.352 +    def get_platform(self):
 137.353 +        return self.info.get('platform', {})    
 137.354      def get_pci_bus(self):
 137.355          return self.info.get('pci_bus', '')
 137.356      def get_tools_version(self):
 137.357          return self.info.get('tools_version', {})
 137.358 +    def get_metrics(self):
 137.359 +        return self.metrics.get_uuid();
 137.360      
 137.361      def get_on_shutdown(self):
 137.362          after_shutdown = self.info.get('actions_after_shutdown')
 137.363 @@ -2278,8 +2286,6 @@ class XendDomainInfo:
 137.364          @return: uuid of the device
 137.365          """
 137.366          xenapi_vbd['image'] = vdi_image_path
 137.367 -        log.debug('create_vbd: %s' % xenapi_vbd)
 137.368 -        dev_uuid = ''
 137.369          if vdi_image_path.startswith('tap'):
 137.370              dev_uuid = self.info.device_add('tap', cfg_xenapi = xenapi_vbd)
 137.371          else:
 137.372 @@ -2289,16 +2295,25 @@ class XendDomainInfo:
 137.373              raise XendError('Failed to create device')
 137.374  
 137.375          if self.state == XEN_API_VM_POWER_STATE_RUNNING:
 137.376 +            
 137.377              _, config = self.info['devices'][dev_uuid]
 137.378 -            dev_control = None
 137.379              
 137.380              if vdi_image_path.startswith('tap'):
 137.381 -                dev_control =  self.getDeviceController('tap')
 137.382 +                dev_control = self.getDeviceController('tap')
 137.383              else:
 137.384                  dev_control = self.getDeviceController('vbd')
 137.385 -                
 137.386 -            config['devid'] = dev_control.createDevice(config)
 137.387 -
 137.388 +
 137.389 +            try:
 137.390 +                devid = dev_control.createDevice(config)
 137.391 +                dev_control.waitForDevice(devid)
 137.392 +                self.info.device_update(dev_uuid,
 137.393 +                                        cfg_xenapi = {'devid': devid})
 137.394 +            except Exception, exn:
 137.395 +                log.exception(exn)
 137.396 +                del self.info['devices'][dev_uuid]
 137.397 +                self.info['vbd_refs'].remove(dev_uuid)
 137.398 +                raise
 137.399 +            
 137.400          return dev_uuid
 137.401  
 137.402      def create_phantom_vbd_with_vdi(self, xenapi_vbd, vdi_image_path):
 137.403 @@ -2332,9 +2347,21 @@ class XendDomainInfo:
 137.404              raise XendError('Failed to create device')
 137.405          
 137.406          if self.state == XEN_API_VM_POWER_STATE_RUNNING:
 137.407 +
 137.408              _, config = self.info['devices'][dev_uuid]
 137.409 -            config['devid'] = self.getDeviceController('vif').createDevice(config)
 137.410 -
 137.411 +            dev_control = self.getDeviceController('vif')
 137.412 +
 137.413 +            try:
 137.414 +                devid = dev_control.createDevice(config)
 137.415 +                dev_control.waitForDevice(devid)
 137.416 +                self.info.device_update(dev_uuid,
 137.417 +                                        cfg_xenapi = {'devid': devid})
 137.418 +            except Exception, exn:
 137.419 +                log.exception(exn)
 137.420 +                del self.info['devices'][dev_uuid]
 137.421 +                self.info['vif_refs'].remove(dev_uuid)
 137.422 +                raise            
 137.423 + 
 137.424          return dev_uuid
 137.425  
 137.426      def create_vtpm(self, xenapi_vtpm):
 137.427 @@ -2401,7 +2428,7 @@ class XendDomainInfo:
 137.428      def __str__(self):
 137.429          return '<domain id=%s name=%s memory=%s state=%s>' % \
 137.430                 (str(self.domid), self.info['name_label'],
 137.431 -                str(self.info['memory_static_min']), DOM_STATES[self.state])
 137.432 +                str(self.info['memory_dynamic_max']), DOM_STATES[self.state])
 137.433  
 137.434      __repr__ = __str__
 137.435  
   138.1 --- a/tools/python/xen/xend/XendError.py	Wed Mar 21 17:03:00 2007 -0500
   138.2 +++ b/tools/python/xen/xend/XendError.py	Wed Mar 21 18:08:31 2007 -0500
   138.3 @@ -13,6 +13,7 @@
   138.4  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   138.5  #============================================================================
   138.6  # Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
   138.7 +# Copyright (c) 2006, 2007 XenSource Inc.
   138.8  #============================================================================
   138.9  
  138.10  from xmlrpclib import Fault
  138.11 @@ -55,6 +56,12 @@ class VmError(XendError):
  138.12      """Vm construction error."""
  138.13      pass
  138.14  
  138.15 +class HVMRequired(VmError):
  138.16 +    def __init__(self):
  138.17 +        XendError.__init__(self,
  138.18 +                           'HVM guest support is unavailable: is VT/AMD-V '
  138.19 +                           'supported by your CPU and enabled in your BIOS?')
  138.20 +
  138.21  
  138.22  XEND_ERROR_AUTHENTICATION_FAILED = ('ELUSER', 'Authentication Failed')
  138.23  XEND_ERROR_SESSION_INVALID       = ('EPERMDENIED', 'Session Invalid')
   139.1 --- a/tools/python/xen/xend/XendLogging.py	Wed Mar 21 17:03:00 2007 -0500
   139.2 +++ b/tools/python/xen/xend/XendLogging.py	Wed Mar 21 18:08:31 2007 -0500
   139.3 @@ -59,6 +59,18 @@ if 'TRACE' not in logging.__dict__:
   139.4                      return filename, frame[2]
   139.5      logging.Logger.findCaller = findCaller
   139.6  
   139.7 +    # Work around a bug in Python's inspect module: findsource is supposed to
   139.8 +    # raise IOError if it fails, with other functions in that module coping
   139.9 +    # with that, but some people are seeing IndexError raised from there.
  139.10 +    if hasattr(inspect, 'findsource'):
  139.11 +        real_findsource = getattr(inspect, 'findsource')
  139.12 +        def findsource(*args, **kwargs):
  139.13 +            try:
  139.14 +                return real_findsource(*args, **kwargs)
  139.15 +            except IndexError, exn:
  139.16 +                raise IOError(exn)
  139.17 +        inspect.findsource = findsource
  139.18 +
  139.19  
  139.20  log = logging.getLogger("xend")
  139.21  
   140.1 --- a/tools/python/xen/xend/XendNode.py	Wed Mar 21 17:03:00 2007 -0500
   140.2 +++ b/tools/python/xen/xend/XendNode.py	Wed Mar 21 18:08:31 2007 -0500
   140.3 @@ -75,6 +75,11 @@ class XendNode:
   140.4              self.other_config = {}
   140.5              self.cpus = {}
   140.6              self.host_metrics_uuid = uuid.createString()
   140.7 +
   140.8 +        # put some arbitrary params in other_config as this
   140.9 +        # is directly exposed via XenAPI
  140.10 +        self.other_config["xen_pagesize"] = self.xeninfo_dict()["xen_pagesize"]
  140.11 +        self.other_config["platform_params"] = self.xeninfo_dict()["platform_params"]
  140.12              
  140.13          # load CPU UUIDs
  140.14          saved_cpus = self.state_store.load_state('cpu')
  140.15 @@ -95,15 +100,12 @@ class XendNode:
  140.16                  self.cpus[u] = {'uuid': u, 'number': i }
  140.17  
  140.18          for u in self.cpus.keys():
  140.19 -            log.error(self.cpus[u])
  140.20              number = self.cpus[u]['number']
  140.21              # We can run off the end of the cpuinfo list if domain0 does not
  140.22              # have #vcpus == #pcpus. In that case we just replicate one that's
  140.23              # in the hash table.
  140.24              if not cpuinfo.has_key(number):
  140.25                  number = cpuinfo.keys()[0]
  140.26 -            log.error(number)
  140.27 -            log.error(cpuinfo)
  140.28              if arch.type == "x86":
  140.29                  self.cpus[u].update(
  140.30                      { 'host'     : self.uuid,
  140.31 @@ -356,14 +358,37 @@ class XendNode:
  140.32  
  140.33      def xen_version(self):
  140.34          info = self.xc.xeninfo()
  140.35 +
  140.36          try:
  140.37              from xen import VERSION
  140.38 -            return {'Xen': '%(xen_major)d.%(xen_minor)d' % info,
  140.39 +            info = {'Xen': '%(xen_major)d.%(xen_minor)d' % info,
  140.40                      'Xend': VERSION}
  140.41          except (ImportError, AttributeError):
  140.42 -            return {'Xen': '%(xen_major)d.%(xen_minor)d' % info,
  140.43 +            info = {'Xen': '%(xen_major)d.%(xen_minor)d' % info,
  140.44                      'Xend': '3.0.3'}
  140.45  
  140.46 +        # Add xend_config_format
  140.47 +        info.update(self.xendinfo_dict())
  140.48 +
  140.49 +        # Add version info about machine
  140.50 +        info.update(self.nodeinfo_dict())
  140.51 +
  140.52 +        # Add specific xen version info
  140.53 +        xeninfo_dict = self.xeninfo_dict()
  140.54 +
  140.55 +        info.update({
  140.56 +            "xen_major":         xeninfo_dict["xen_major"],
  140.57 +            "xen_minor":         xeninfo_dict["xen_minor"],
  140.58 +            "xen_extra":         xeninfo_dict["xen_extra"],
  140.59 +            "cc_compiler":       xeninfo_dict["cc_compiler"],
  140.60 +            "cc_compile_by":     xeninfo_dict["cc_compile_by"],
  140.61 +            "cc_compile_domain": xeninfo_dict["cc_compile_domain"],
  140.62 +            "cc_compile_date":   xeninfo_dict["cc_compile_date"],
  140.63 +            "xen_changeset":     xeninfo_dict["xen_changeset"]
  140.64 +            })
  140.65 +        
  140.66 +        return info
  140.67 +
  140.68      def get_name(self):
  140.69          return self.name
  140.70  
  140.71 @@ -418,6 +443,27 @@ class XendNode:
  140.72  
  140.73          return 0.0
  140.74  
  140.75 +    def get_vcpus_policy(self):
  140.76 +        sched_id = self.xc.sched_id_get()
  140.77 +        if sched_id == xen.lowlevel.xc.XEN_SCHEDULER_SEDF:
  140.78 +            return 'sedf'
  140.79 +        elif sched_id == xen.lowlevel.xc.XEN_SCHEDULER_CREDIT:
  140.80 +            return 'credit'
  140.81 +        else:
  140.82 +            return 'unknown'
  140.83 +
  140.84 +    def get_cpu_configuration(self):
  140.85 +        phys_info = self.physinfo_dict()
  140.86 +
  140.87 +        cpu_info = {
  140.88 +            "nr_nodes":         phys_info["nr_nodes"],
  140.89 +            "sockets_per_node": phys_info["sockets_per_node"],
  140.90 +            "cores_per_socket": phys_info["cores_per_socket"],
  140.91 +            "threads_per_core": phys_info["threads_per_core"]
  140.92 +            }
  140.93 +
  140.94 +        return cpu_info
  140.95 +    
  140.96      #
  140.97      # Network Functions
  140.98      #
  140.99 @@ -453,6 +499,12 @@ class XendNode:
 140.100                  return pif.network
 140.101          raise Exception('Bridge %s is not connected to a network' % bridge)
 140.102  
 140.103 +    #
 140.104 +    # Debug keys.
 140.105 +    #
 140.106 +
 140.107 +    def send_debug_keys(self, keys):
 140.108 +        return self.xc.send_debug_keys(keys)
 140.109  
 140.110      #
 140.111      # Getting host information.
 140.112 @@ -478,7 +530,8 @@ class XendNode:
 140.113                             info['cores_per_socket'] *
 140.114                             info['threads_per_core'])
 140.115          info['cpu_mhz'] = info['cpu_khz'] / 1000
 140.116 -        # physinfo is in KiB
 140.117 +        
 140.118 +        # physinfo is in KiB, need it in MiB
 140.119          info['total_memory'] = info['total_memory'] / 1024
 140.120          info['free_memory']  = info['free_memory'] / 1024
 140.121  
   141.1 --- a/tools/python/xen/xend/XendVDI.py	Wed Mar 21 17:03:00 2007 -0500
   141.2 +++ b/tools/python/xen/xend/XendVDI.py	Wed Mar 21 18:08:31 2007 -0500
   141.3 @@ -54,7 +54,6 @@ class XendVDI(AutoSaveObject):
   141.4      
   141.5      SAVED_CFG = ['name_label',
   141.6                   'name_description',
   141.7 -                 'sector_size',
   141.8                   'virtual_size',
   141.9                   'physical_utilisation',
  141.10                   'sharable',
  141.11 @@ -67,13 +66,22 @@ class XendVDI(AutoSaveObject):
  141.12          self.sr_uuid = sr_uuid
  141.13          self.name_label = ""
  141.14          self.name_description = ""
  141.15 -        self.sector_size = 1024
  141.16          self.virtual_size = 0
  141.17          self.physical_utilisation = 0
  141.18          self.sharable = False
  141.19          self.read_only = False
  141.20          self.type = "system"
  141.21 -        self.location = ''
  141.22 +        self.other_config = {}
  141.23 +        self.vbds = []
  141.24 +
  141.25 +    def addVBD(self, vbd_ref):
  141.26 +        self.vbds.append(vbd_ref)
  141.27 +
  141.28 +    def removeVBD(self, vbd_ref):
  141.29 +        self.vbds.remove(vbd_ref)
  141.30 +
  141.31 +    def getVBDs(self):
  141.32 +        return self.vbds
  141.33  
  141.34      def load_config_dict(self, cfg):
  141.35          """Loads configuration into the object from a dict.
  141.36 @@ -144,11 +152,10 @@ class XendVDI(AutoSaveObject):
  141.37                  'name_description': self.name_description,
  141.38                  'virtual_size': self.virtual_size,
  141.39                  'physical_utilisation': self.physical_utilisation,
  141.40 -                'sector_size': self.sector_size,
  141.41                  'sharable': False,
  141.42                  'readonly': False,
  141.43                  'SR': self.sr_uuid,
  141.44 -                'location': self.get_location(),
  141.45 +                'other_config': self.other_config,
  141.46                  'VBDs': []}
  141.47  
  141.48      def get_location(self):
  141.49 @@ -163,12 +170,11 @@ class XendQCoWVDI(XendVDI):
  141.50          self.cfg_path = cfg_path
  141.51          self.physical_utilisation = psize
  141.52          self.virtual_size = vsize
  141.53 -        self.sector_size = 512
  141.54          self.auto_save = True
  141.55 -        self.location = 'tap:qcow:%s' % self.qcow_path
  141.56 +        self.other_config['location'] = 'tap:qcow:%s' % self.qcow_path
  141.57  
  141.58      def get_location(self):
  141.59 -        return self.location
  141.60 +        return self.other_config['location']
  141.61  
  141.62  class XendLocalVDI(XendVDI):
  141.63      def __init__(self, vdi_struct):
  141.64 @@ -182,11 +188,10 @@ class XendLocalVDI(XendVDI):
  141.65          self.name_description = vdi_struct.get('name_description', '')
  141.66          self.physical_utilisation = 0
  141.67          self.virtual_size = 0
  141.68 -        self.sector_size = 0
  141.69          self.type = vdi_struct.get('type', '')
  141.70          self.sharable = vdi_struct.get('sharable', False)
  141.71          self.read_only = vdi_struct.get('read_only', False)
  141.72 -        self.location = vdi_struct.get('location', 'file:/dev/null')
  141.73 +        self.other_config = vdi_struct.get('other_config', {})
  141.74  
  141.75      def get_location(self):
  141.76 -        return self.location
  141.77 +        return self.other_config['location']
   142.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   142.2 +++ b/tools/python/xen/xend/XendVMMetrics.py	Wed Mar 21 18:08:31 2007 -0500
   142.3 @@ -0,0 +1,70 @@
   142.4 +#============================================================================
   142.5 +# This library is free software; you can redistribute it and/or
   142.6 +# modify it under the terms of version 2.1 of the GNU Lesser General Public
   142.7 +# License as published by the Free Software Foundation.
   142.8 +#
   142.9 +# This library is distributed in the hope that it will be useful,
  142.10 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
  142.11 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  142.12 +# Lesser General Public License for more details.
  142.13 +#
  142.14 +# You should have received a copy of the GNU Lesser General Public
  142.15 +# License along with this library; if not, write to the Free Software
  142.16 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  142.17 +#============================================================================
  142.18 +# Copyright (c) 2006-2007 Xensource Inc.
  142.19 +#============================================================================
  142.20 +
  142.21 +from xen.xend.XendLogging import log
  142.22 +
  142.23 +instances = {}
  142.24 +
  142.25 +class XendVMMetrics:
  142.26 +    """VM Metrics."""
  142.27 +
  142.28 +    def get_by_uuid(_, uuid):
  142.29 +        return instances[uuid]
  142.30 +
  142.31 +    get_by_uuid = classmethod(get_by_uuid)
  142.32 +
  142.33 +    def is_valid_vm_metrics(_, uuid):
  142.34 +        return uuid in instances
  142.35 +
  142.36 +    is_valid_vm_metrics = classmethod(is_valid_vm_metrics)
  142.37 +
  142.38 +    def get_all(_):
  142.39 +        return instances.keys()
  142.40 +
  142.41 +    get_all = classmethod(get_all)
  142.42 +   
  142.43 +    def __init__(self, uuid, xend_domain_instance):
  142.44 +        self.uuid = uuid
  142.45 +        self.xend_domain_instance = xend_domain_instance
  142.46 +        instances[uuid] = self
  142.47 +
  142.48 +    def get_uuid(self):
  142.49 +        return self.uuid
  142.50 +
  142.51 +    def get_memory_actual(self):
  142.52 +        return self.get_record()["memory_actual"]
  142.53 +
  142.54 +    def get_vcpus_number(self):
  142.55 +        return self.get_record()["vcpus_number"]
  142.56 +    
  142.57 +    def get_vcpus_utilisation(self):
  142.58 +        return self.xend_domain_instance.get_vcpus_util()
  142.59 +
  142.60 +    def get_record(self):
  142.61 +        domInfo = self.xend_domain_instance.getDomInfo()
  142.62 +        if domInfo:
  142.63 +            return { 'uuid'              : self.uuid,
  142.64 +                     'memory_actual'     : domInfo["mem_kb"] * 1024,
  142.65 +                     'vcpus_number'      : domInfo["online_vcpus"],
  142.66 +                     'vcpus_utilisation' : self.get_vcpus_utilisation()
  142.67 +                   }
  142.68 +        else:
  142.69 +            return { 'uuid'              : self.uuid,
  142.70 +                     'memory_actual'     : 0,
  142.71 +                     'vcpus_number'      : 0,
  142.72 +                     'vcpus_utilisation' : {}
  142.73 +                   }
   143.1 --- a/tools/python/xen/xend/image.py	Wed Mar 21 17:03:00 2007 -0500
   143.2 +++ b/tools/python/xen/xend/image.py	Wed Mar 21 18:08:31 2007 -0500
   143.3 @@ -13,7 +13,7 @@
   143.4  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   143.5  #============================================================================
   143.6  # Copyright (C) 2005 Mike Wray <mike.wray@hp.com>
   143.7 -# Copyright (C) 2005 XenSource Ltd
   143.8 +# Copyright (C) 2005-2007 XenSource Ltd
   143.9  #============================================================================
  143.10  
  143.11  
  143.12 @@ -24,7 +24,7 @@ import signal
  143.13  
  143.14  import xen.lowlevel.xc
  143.15  from xen.xend.XendConstants import REVERSE_DOMAIN_SHUTDOWN_REASONS
  143.16 -from xen.xend.XendError import VmError, XendError
  143.17 +from xen.xend.XendError import VmError, XendError, HVMRequired
  143.18  from xen.xend.XendLogging import log
  143.19  from xen.xend.XendOptions import instance as xenopts
  143.20  from xen.xend.server.netif import randomMAC
  143.21 @@ -36,13 +36,12 @@ xc = xen.lowlevel.xc.xc()
  143.22  MAX_GUEST_CMDLINE = 1024
  143.23  
  143.24  
  143.25 -def create(vm, vmConfig, imageConfig, deviceConfig):
  143.26 +def create(vm, vmConfig):
  143.27      """Create an image handler for a vm.
  143.28  
  143.29      @return ImageHandler instance
  143.30      """
  143.31 -    return findImageHandlerClass(imageConfig)(vm, vmConfig, imageConfig,
  143.32 -                                              deviceConfig)
  143.33 +    return findImageHandlerClass(vmConfig)(vm, vmConfig)
  143.34  
  143.35  
  143.36  class ImageHandler:
  143.37 @@ -65,7 +64,7 @@ class ImageHandler:
  143.38      ostype = None
  143.39  
  143.40  
  143.41 -    def __init__(self, vm, vmConfig, imageConfig, deviceConfig):
  143.42 +    def __init__(self, vm, vmConfig):
  143.43          self.vm = vm
  143.44  
  143.45          self.bootloader = False
  143.46 @@ -73,9 +72,9 @@ class ImageHandler:
  143.47          self.ramdisk = None
  143.48          self.cmdline = None
  143.49  
  143.50 -        self.configure(vmConfig, imageConfig, deviceConfig)
  143.51 +        self.configure(vmConfig)
  143.52  
  143.53 -    def configure(self, vmConfig, imageConfig, _):
  143.54 +    def configure(self, vmConfig):
  143.55          """Config actions common to all unix-like domains."""
  143.56          if '_temp_using_bootloader' in vmConfig:
  143.57              self.bootloader = True
  143.58 @@ -233,30 +232,29 @@ class HVMImageHandler(ImageHandler):
  143.59  
  143.60      ostype = "hvm"
  143.61  
  143.62 -    def __init__(self, vm, vmConfig, imageConfig, deviceConfig):
  143.63 -        ImageHandler.__init__(self, vm, vmConfig, imageConfig, deviceConfig)
  143.64 +    def __init__(self, vm, vmConfig):
  143.65 +        ImageHandler.__init__(self, vm, vmConfig)
  143.66          self.shutdownWatch = None
  143.67          self.rebootFeatureWatch = None
  143.68  
  143.69 -    def configure(self, vmConfig, imageConfig, deviceConfig):
  143.70 -        ImageHandler.configure(self, vmConfig, imageConfig, deviceConfig)
  143.71 +    def configure(self, vmConfig):
  143.72 +        ImageHandler.configure(self, vmConfig)
  143.73  
  143.74          if not self.kernel:
  143.75              self.kernel = '/usr/lib/xen/boot/hvmloader'
  143.76  
  143.77          info = xc.xeninfo()
  143.78          if 'hvm' not in info['xen_caps']:
  143.79 -            raise VmError("HVM guest support is unavailable: is VT/AMD-V "
  143.80 -                          "supported by your CPU and enabled in your BIOS?")
  143.81 +            raise HVMRequired()
  143.82  
  143.83          self.dmargs = self.parseDeviceModelArgs(vmConfig)
  143.84 -        self.device_model = imageConfig['hvm'].get('device_model')
  143.85 +        self.device_model = vmConfig['platform'].get('device_model')
  143.86          if not self.device_model:
  143.87              raise VmError("hvm: missing device model")
  143.88          
  143.89 -        self.display = imageConfig['hvm'].get('display')
  143.90 -        self.xauthority = imageConfig['hvm'].get('xauthority')
  143.91 -        self.vncconsole = imageConfig['hvm'].get('vncconsole')
  143.92 +        self.display = vmConfig['platform'].get('display')
  143.93 +        self.xauthority = vmConfig['platform'].get('xauthority')
  143.94 +        self.vncconsole = vmConfig['platform'].get('vncconsole')
  143.95  
  143.96          self.vm.storeVm(("image/dmargs", " ".join(self.dmargs)),
  143.97                          ("image/device-model", self.device_model),
  143.98 @@ -264,9 +262,9 @@ class HVMImageHandler(ImageHandler):
  143.99  
 143.100          self.pid = None
 143.101  
 143.102 -        self.pae  = imageConfig['hvm'].get('pae', 0)
 143.103 -        self.apic  = imageConfig['hvm'].get('apic', 0)
 143.104 -        self.acpi  = imageConfig['hvm']['devices'].get('acpi', 0)
 143.105 +        self.pae  = int(vmConfig['platform'].get('pae',  0))
 143.106 +        self.apic = int(vmConfig['platform'].get('apic', 0))
 143.107 +        self.acpi = int(vmConfig['platform'].get('acpi', 0))
 143.108          
 143.109  
 143.110      def buildDomain(self):
 143.111 @@ -302,11 +300,10 @@ class HVMImageHandler(ImageHandler):
 143.112                     'localtime', 'serial', 'stdvga', 'isa',
 143.113                     'acpi', 'usb', 'usbdevice', 'keymap' ]
 143.114          
 143.115 -        hvmDeviceConfig = vmConfig['image']['hvm']['devices']
 143.116          ret = ['-vcpus', str(self.vm.getVCpuCount())]
 143.117  
 143.118          for a in dmargs:
 143.119 -            v = hvmDeviceConfig.get(a)
 143.120 +            v = vmConfig['platform'].get(a)
 143.121  
 143.122              # python doesn't allow '-' in variable names
 143.123              if a == 'stdvga': a = 'std-vga'
 143.124 @@ -366,14 +363,14 @@ class HVMImageHandler(ImageHandler):
 143.125          # Find RFB console device, and if it exists, make QEMU enable
 143.126          # the VNC console.
 143.127          #
 143.128 -        if vmConfig['image'].get('nographic'):
 143.129 +        if int(vmConfig['platform'].get('nographic', 0)) != 0:
 143.130              # skip vnc init if nographic is set
 143.131              ret.append('-nographic')
 143.132              return ret
 143.133  
 143.134          vnc_config = {}
 143.135 -        has_vnc = int(vmConfig['image'].get('vnc', 0)) != 0
 143.136 -        has_sdl = int(vmConfig['image'].get('sdl', 0)) != 0
 143.137 +        has_vnc = int(vmConfig['platform'].get('vnc', 0)) != 0
 143.138 +        has_sdl = int(vmConfig['platform'].get('sdl', 0)) != 0
 143.139          for dev_uuid in vmConfig['console_refs']:
 143.140              dev_type, dev_info = vmConfig['devices'][dev_uuid]
 143.141              if dev_type == 'vfb':
 143.142 @@ -385,8 +382,8 @@ class HVMImageHandler(ImageHandler):
 143.143              if not vnc_config:
 143.144                  for key in ('vncunused', 'vnclisten', 'vncdisplay',
 143.145                              'vncpasswd'):
 143.146 -                    if key in vmConfig['image']:
 143.147 -                        vnc_config[key] = vmConfig['image'][key]
 143.148 +                    if key in vmConfig['platform']:
 143.149 +                        vnc_config[key] = vmConfig['platform'][key]
 143.150  
 143.151              if not vnc_config.get('vncunused', 0) and \
 143.152                     vnc_config.get('vncdisplay', 0):
 143.153 @@ -604,9 +601,7 @@ def findImageHandlerClass(image):
 143.154      @param image config
 143.155      @return ImageHandler subclass or None
 143.156      """
 143.157 -    image_type = image['type']
 143.158 -    if image_type is None:
 143.159 -        raise VmError('missing image type')
 143.160 +    image_type = image.image_type()
 143.161      try:
 143.162          return _handlers[arch.type][image_type]
 143.163      except KeyError:
   144.1 --- a/tools/python/xen/xend/server/SrvDaemon.py	Wed Mar 21 17:03:00 2007 -0500
   144.2 +++ b/tools/python/xen/xend/server/SrvDaemon.py	Wed Mar 21 18:08:31 2007 -0500
   144.3 @@ -276,9 +276,12 @@ class Daemon:
   144.4              if not m:
   144.5                  return None
   144.6              modulename = m.group(1)
   144.7 -            if re.search('sxp.py', modulename):
   144.8 -                return None
   144.9 -            if re.search('SrvServer.py', modulename):
  144.10 +            if modulename.endswith('.pyc'):
  144.11 +                modulename = modulename[:-1]
  144.12 +            if modulename == 'sxp.py' or \
  144.13 +               modulename == 'XendLogging.py' or \
  144.14 +               modulename == 'XendMonitor.py' or \
  144.15 +               modulename == 'server/SrvServer.py':
  144.16                  return None
  144.17              self.traceindent += 1
  144.18              self.print_trace("> %s:%s\n"
   145.1 --- a/tools/python/xen/xend/server/XMLRPCServer.py	Wed Mar 21 17:03:00 2007 -0500
   145.2 +++ b/tools/python/xen/xend/server/XMLRPCServer.py	Wed Mar 21 18:08:31 2007 -0500
   145.3 @@ -157,7 +157,7 @@ class XMLRPCServer:
   145.4                      self.server.register_function(fn, "xend.domain.%s" % name[7:])
   145.5  
   145.6          # Functions in XendNode and XendDmesg
   145.7 -        for type, lst, n in [(XendNode, ['info'], 'node'),
   145.8 +        for type, lst, n in [(XendNode, ['info', 'send_debug_keys'], 'node'),
   145.9                               (XendDmesg, ['info', 'clear'], 'node.dmesg')]:
  145.10              inst = type.instance()
  145.11              for name in lst:
   146.1 --- a/tools/python/xen/xend/server/vfbif.py	Wed Mar 21 17:03:00 2007 -0500
   146.2 +++ b/tools/python/xen/xend/server/vfbif.py	Wed Mar 21 18:08:31 2007 -0500
   146.3 @@ -46,7 +46,7 @@ class VfbifController(DevController):
   146.4  
   146.5      def createDevice(self, config):
   146.6          DevController.createDevice(self, config)
   146.7 -        if self.vm.info.get('HVM_boot_policy'):
   146.8 +        if self.vm.info.is_hvm():
   146.9              # is HVM, so qemu-dm will handle the vfb.
  146.10              return
  146.11          
   147.1 --- a/tools/python/xen/xm/XenAPI.py	Wed Mar 21 17:03:00 2007 -0500
   147.2 +++ b/tools/python/xen/xm/XenAPI.py	Wed Mar 21 18:08:31 2007 -0500
   147.3 @@ -155,7 +155,7 @@ class Session(xen.util.xmlrpclib2.Server
   147.4  
   147.5  def _parse_result(result):
   147.6      if type(result) != dict or 'Status' not in result:
   147.7 -        raise xmlrpclib.Fault(500, 'Missing Status in response from server')
   147.8 +        raise xmlrpclib.Fault(500, 'Missing Status in response from server: ' + str(result))
   147.9      if result['Status'] == 'Success':
  147.10