[Pkg-xen-changes] [xen] 01/30: Import xen_4.5.0.orig.tar.xz

Ian James Campbell ijc at moszumanska.debian.org
Tue Jan 20 15:15:32 UTC 2015


This is an automated email from the git hooks/post-receive script.

ijc pushed a commit to branch feature/experimental-4.5-final
in repository xen.

commit 1e4a195fdf38d618847a335755b6c2de4f8151a9
Author: Ian Campbell <ijc at debian.org>
Date:   Tue Jan 20 13:27:28 2015 +0000

    Import xen_4.5.0.orig.tar.xz
---
 .gitignore                                         |  12 +-
 Config.mk                                          |  14 +-
 INSTALL                                            |   2 +-
 README                                             |  49 +++-
 docs/misc/xen-command-line.markdown                |  22 +-
 m4/systemd.m4                                      |  12 +-
 tools/configure                                    | 149 +++++------
 tools/flask/policy/policy/modules/xen/xen.if       |  11 +-
 tools/flask/policy/policy/modules/xen/xen.te       |   3 +
 .../Linux/systemd/var-lib-xenstored.mount.in       |   4 +-
 .../hotplug/Linux/systemd/xen-init-dom0.service.in |   4 +-
 .../systemd/xen-qemu-dom0-disk-backend.service.in  |   5 +-
 tools/hotplug/Linux/systemd/xenconsoled.service.in |  10 +-
 tools/hotplug/Linux/systemd/xendomains.service.in  |   6 +-
 tools/hotplug/Linux/systemd/xenstored.service.in   |   1 -
 tools/libxc/xc_domain_restore.c                    |   2 +-
 tools/libxc/xc_private.c                           |   6 +-
 tools/libxl/Makefile                               |   6 +-
 tools/libxl/libxl.c                                |  46 +++-
 tools/libxl/libxl.h                                |  10 +
 tools/libxl/libxl_dm.c                             |  15 +-
 tools/libxl/libxl_dom.c                            |  17 +-
 tools/libxl/libxl_event.c                          |  34 ++-
 tools/libxl/libxl_event.h                          |   6 +-
 tools/libxl/libxl_fork.c                           |   9 +-
 tools/libxl/libxl_internal.h                       |   8 +-
 tools/libxl/libxl_pci.c                            |   8 +-
 tools/libxl/libxl_utils.c                          |   5 +-
 tools/libxl/libxl_utils.h                          |   6 +-
 tools/libxl/libxlu_cfg_l.c                         |   8 +-
 tools/libxl/libxlu_cfg_l.h                         |   6 +-
 tools/libxl/libxlu_cfg_y.c                         |   4 +-
 tools/libxl/libxlu_cfg_y.y                         |   6 +-
 tools/libxl/libxlu_disk_l.c                        |   8 +-
 tools/libxl/libxlu_disk_l.h                        |   6 +-
 tools/libxl/xl.h                                   |   2 +-
 tools/libxl/xl_cmdimpl.c                           |  31 ++-
 tools/libxl/xl_sxp.c                               | 228 ++++++++---------
 tools/pygrub/src/pygrub                            |   4 +-
 tools/python/xen/lowlevel/xc/xc.c                  |  34 +--
 tools/python/xen/lowlevel/xs/xs.c                  |   2 +-
 tools/xenstore/Makefile                            |  10 +-
 tools/xenstore/include/xenstore.h                  |  12 +-
 xen/Makefile                                       |   2 +-
 xen/arch/arm/setup.c                               |   3 +-
 xen/arch/arm/time.c                                |  13 +
 xen/arch/arm/vgic.c                                |   2 +
 xen/arch/x86/domain.c                              |   4 +-
 xen/arch/x86/domain_build.c                        |   9 +-
 xen/arch/x86/hvm/hvm.c                             |  30 ++-
 xen/arch/x86/hvm/svm/svm.c                         |  20 +-
 xen/arch/x86/hvm/svm/vpmu.c                        |   3 -
 xen/arch/x86/hvm/vmx/vmx.c                         |  32 +--
 xen/arch/x86/hvm/vmx/vpmu_core2.c                  |   2 -
 xen/arch/x86/hvm/vpmu.c                            |  20 ++
 xen/arch/x86/io_apic.c                             |  12 +
 xen/arch/x86/microcode_amd.c                       |  18 +-
 xen/arch/x86/mm.c                                  |   9 +-
 xen/arch/x86/setup.c                               |   1 +
 xen/arch/x86/traps.c                               |   4 +-
 xen/arch/x86/x86_64/compat/mm.c                    |   7 +-
 xen/arch/x86/x86_64/mm.c                           |   7 +-
 xen/common/compat/grant_table.c                    |   2 +
 xen/common/domain.c                                |   7 +-
 xen/common/domctl.c                                |  15 +-
 xen/common/efi/boot.c                              |   1 +
 xen/common/grant_table.c                           |  11 +-
 xen/common/mem_access.c                            |  18 +-
 xen/common/memory.c                                |  18 ++
 xen/common/spinlock.c                              | 136 ++++++----
 xen/drivers/char/console.c                         |  24 +-
 xen/drivers/char/omap-uart.c                       |   3 +
 xen/drivers/passthrough/io.c                       | 284 ++-------------------
 xen/drivers/passthrough/pci.c                      |  29 +--
 xen/drivers/passthrough/vtd/iommu.c                |  26 +-
 xen/drivers/passthrough/vtd/iommu.h                |   2 +-
 xen/drivers/passthrough/vtd/quirks.c               |  46 +++-
 xen/drivers/passthrough/vtd/utils.c                |   6 +-
 xen/include/asm-arm/arm32/bug.h                    |   2 +-
 xen/include/asm-arm/arm32/spinlock.h               |  78 ------
 xen/include/asm-arm/arm64/spinlock.h               |  63 -----
 xen/include/asm-arm/irq.h                          |   2 +-
 xen/include/asm-x86/setup.h                        |   2 +
 xen/include/asm-x86/softirq.h                      |   3 +-
 xen/include/asm-x86/spinlock.h                     |  54 ----
 xen/include/xen/8250-uart.h                        |   4 +
 xen/include/xen/console.h                          |   1 +
 xen/include/xen/hvm/irq.h                          |   4 +-
 xen/include/xen/hypercall.h                        |   5 +
 xen/include/xen/iocap.h                            |  17 +-
 xen/include/xen/irq.h                              |   4 +
 xen/include/xen/pci.h                              |   2 +-
 xen/include/xen/spinlock.h                         |   6 +-
 93 files changed, 893 insertions(+), 1023 deletions(-)

diff --git a/.gitignore b/.gitignore
index b24e905..8c8c06f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -141,12 +141,19 @@ tools/flask/utils/flask-set-bool
 tools/flask/utils/flask-label-pci
 tools/hotplug/common/hotplugpath.sh
 tools/hotplug/FreeBSD/rc.d/xencommons
+tools/hotplug/Linux/init.d/sysconfig.xencommons
 tools/hotplug/Linux/init.d/xen-watchdog
+tools/hotplug/Linux/init.d/xencommons
 tools/hotplug/Linux/init.d/xendomains
+tools/hotplug/Linux/systemd/*.conf
+tools/hotplug/Linux/systemd/*.mount
+tools/hotplug/Linux/systemd/*.socket
+tools/hotplug/Linux/systemd/*.service
 tools/hotplug/Linux/vif-setup
 tools/hotplug/Linux/xen-backend.rules
 tools/hotplug/Linux/xen-hotplug-common.sh
 tools/hotplug/Linux/xendomains
+tools/hotplug/NetBSD/rc.d/xencommons
 tools/include/xen/*
 tools/include/xen-foreign/*.(c|h|size)
 tools/include/xen-foreign/checker
@@ -326,8 +333,3 @@ tools/xenstore/xenstore-watch
 docs/txt/misc/*.txt
 docs/txt/man/*.txt
 docs/figs/*.png
-
-tools/hotplug/Linux/systemd/*.conf
-tools/hotplug/Linux/systemd/*.mount
-tools/hotplug/Linux/systemd/*.socket
-tools/hotplug/Linux/systemd/*.service
diff --git a/Config.mk b/Config.mk
index a53cfb5..7288326 100644
--- a/Config.mk
+++ b/Config.mk
@@ -17,7 +17,7 @@ or       = $(if $(strip $(1)),$(1),$(if $(strip $(2)),$(2),$(if $(strip $(3)),$(
 -include $(XEN_ROOT)/.config
 
 # A debug build of Xen and tools?
-debug ?= y
+debug ?= n
 debug_symbols ?= $(debug)
 
 # Test coverage support
@@ -242,17 +242,17 @@ endif
 
 ifeq ($(GIT_HTTP),y)
 OVMF_UPSTREAM_URL ?= http://xenbits.xen.org/git-http/ovmf.git
-QEMU_UPSTREAM_URL ?= http://xenbits.xen.org/git-http/qemu-upstream-unstable.git
-QEMU_TRADITIONAL_URL ?= http://xenbits.xen.org/git-http/qemu-xen-unstable.git
+QEMU_UPSTREAM_URL ?= http://xenbits.xen.org/git-http/qemu-upstream-4.5-testing.git
+QEMU_TRADITIONAL_URL ?= http://xenbits.xen.org/git-http/qemu-xen-4.5-testing.git
 SEABIOS_UPSTREAM_URL ?= http://xenbits.xen.org/git-http/seabios.git
 else
 OVMF_UPSTREAM_URL ?= git://xenbits.xen.org/ovmf.git
-QEMU_UPSTREAM_URL ?= git://xenbits.xen.org/qemu-upstream-unstable.git
-QEMU_TRADITIONAL_URL ?= git://xenbits.xen.org/qemu-xen-unstable.git
+QEMU_UPSTREAM_URL ?= git://xenbits.xen.org/qemu-upstream-4.5-testing.git
+QEMU_TRADITIONAL_URL ?= git://xenbits.xen.org/qemu-xen-4.5-testing.git
 SEABIOS_UPSTREAM_URL ?= git://xenbits.xen.org/seabios.git
 endif
 OVMF_UPSTREAM_REVISION ?= 447d264115c476142f884af0be287622cd244423
-QEMU_UPSTREAM_REVISION ?= qemu-xen-4.5.0-rc3
+QEMU_UPSTREAM_REVISION ?= qemu-xen-4.5.0
 SEABIOS_UPSTREAM_REVISION ?= rel-1.7.5
 # Thu May 22 16:59:16 2014 -0400
 # python3 fixes for vgabios and csm builds.
@@ -260,7 +260,7 @@ SEABIOS_UPSTREAM_REVISION ?= rel-1.7.5
 ETHERBOOT_NICS ?= rtl8139 8086100e
 
 
-QEMU_TRADITIONAL_REVISION ?= xen-4.5.0-rc1
+QEMU_TRADITIONAL_REVISION ?= xen-4.5.0
 # Mon Oct 6 16:24:46 2014 +0100
 # qemu-xen-trad: Switch to $(LIBEXEC_BIN) from $(LIBEXEC)
 
diff --git a/INSTALL b/INSTALL
index 0bc67ea..71dd0eb 100644
--- a/INSTALL
+++ b/INSTALL
@@ -284,7 +284,7 @@ systemctl enable xen-init-dom0.service
 systemctl enable xenconsoled.service
 
 Other optional services are:
-systemctl enable xen-domains.service
+systemctl enable xendomains.service
 systemctl enable xen-watchdog.service
 
 
diff --git a/README b/README
index 412607a..3bdc74e 100644
--- a/README
+++ b/README
@@ -1,9 +1,9 @@
 #################################
-__  __            _  _    ____                        _        _     _      
-\ \/ /___ _ __   | || |  | ___|       _   _ _ __  ___| |_ __ _| |__ | | ___ 
- \  // _ \ '_ \  | || |_ |___ \ _____| | | | '_ \/ __| __/ _` | '_ \| |/ _ \
- /  \  __/ | | | |__   _| ___) |_____| |_| | | | \__ \ || (_| | |_) | |  __/
-/_/\_\___|_| |_|    |_|(_)____/       \__,_|_| |_|___/\__\__,_|_.__/|_|\___|
+__  __            _  _    ____   ___
+\ \/ /___ _ __   | || |  | ___| / _ \
+ \  // _ \ '_ \  | || |_ |___ \| | | |
+ /  \  __/ | | | |__   _| ___) | |_| |
+/_/\_\___|_| |_|    |_|(_)____(_)___/
 
 #################################
 
@@ -19,14 +19,37 @@ is freely-distributable Open Source software, released under the GNU
 GPL. Since its initial public release, Xen has grown a large
 development community, spearheaded by xen.org (http://www.xen.org).
 
-The 4.3 release offers a number of improvements, including NUMA
-scheduling affinity, openvswitch integration, and defaulting to
-qemu-xen rather than qemu-traditional for non-stubdom guests.
-(qemu-xen is kept very close to the upstream project.)  We also have a
-number of updates to vTPM, and improvements to XSM and Flask to allow
-greater disaggregation.  Additionally, 4.3 contains a basic version of
-Xen for the new ARM server architecture, both 32- and 64-bit.  And as
-always, there are a number of performance, stability, and security
+The 4.5 release offers a number of improvements, including:
+improvements for large scale machines during bootup and for PCI
+passthrough; multiple IO-REQ servers (many QEMUs for a guest); soft
+affinity for vCPUs (aka NUMA affinity); and API expansion for guest
+introspection.  We also have number of updates for CPU specific
+changes, such as: Broadwell Supervisor Mode Access Prevention; Haswell
+Server Cache QoS Monitoring aka Intel Resource Director Technology;
+further extensions to vAPIC (SandyBridge feature); fixes in AMD
+microcode loading; Data Breaking Extensions; and further MSR masking
+support on AMD.
+
+On the experimental side we have added a new Real-Time Deferrable
+Server Based CPU Scheduler (rtds), and PVH initial domain (dom0)
+support for Intel CPUs.
+
+Additionally, 4.5 has a huge update to the ARM code, including support
+for: up to 1TB in guests; up to 8 CPUs; Power State Coordination
+Interface (0.2) to power up and down CPUs; UEFI booting; IOMMU support
+(SMMUv1); Super Page (2MB) support; passthrough of MMIO regions to
+guests; and lower interrupt latency.
+
+The toolstack has expanded to include support for: VM Generation ID (a
+Windows 2012 Server requirement); Remus initial support (for high
+availability) in libxl (since xend has been removed); libxenlight JSON
+support, HVM guest direct kernel boot, and persistent configuration
+support; systemd support; performance optimizations in oxenstored;
+and support in QEMU for expanding the PCI hole.
+
+Lastly, we have removed the Python toolstack (xend).
+
+And as always, there are a number of performance, stability, and security
 improvements under-the hood.
 
 This file contains some quick-start instructions to install Xen on
diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown
index 0866df2..152ae03 100644
--- a/docs/misc/xen-command-line.markdown
+++ b/docs/misc/xen-command-line.markdown
@@ -596,13 +596,16 @@ Force or disable use of EFI runtime services.
 ### extra\_guest\_irqs
 > `= [<domU number>][,<dom0 number>]`
 
-> Default: `32,256`
+> Default: `32,<variable>`
 
 Change the number of PIRQs available for guests.  The optional first number is
 common for all domUs, while the optional second number (preceded by a comma)
 is for dom0.  Changing the setting for domU has no impact on dom0 and vice
 versa.  For example to change dom0 without changing domU, use
-`extra_guest_irqs=,512`
+`extra_guest_irqs=,512`.  The default value for Dom0 and an eventual separate
+hardware domain is architecture dependent.
+Note that specifying zero as domU value means zero, while for dom0 it means
+to use the default.
 
 ### flask\_enabled
 > `= <integer>`
@@ -611,7 +614,7 @@ versa.  For example to change dom0 without changing domU, use
 > `= <integer>`
 
 ### font
-> `= <height>` where height is `8x8 | 8x14 | 8x16 '`
+> `= <height>` where height is `8x8 | 8x14 | 8x16`
 
 Specify the font size when using the VESA console driver.
 
@@ -645,13 +648,13 @@ Specify the maximum number of frames per grant table operation.
 > `= <integer>`
 
 Specify the maximum number of maptrack frames domain.
-The default value is 8 times gnttab_max_frames.
+The default value is 8 times **gnttab\_max\_frames**.
 
 ### gnttab\_max\_nr\_frames
 > `= <integer>`
 
 *Deprecated*
-Use gnttab\_max\_frames and gnttab\_max\_maptrack\_frames instead.
+Use **gnttab\_max\_frames** and **gnttab\_max\_maptrack\_frames** instead.
 
 Specify the maximum number of frames per grant table operation and the
 maximum number of maptrack frames domain.
@@ -983,7 +986,7 @@ of the ACPI based one.
 ### nmi
 > `= ignore | dom0 | fatal`
 
-> Default: `nmi=fatal`
+> Default: `fatal` for a debug build, or `dom0` for a non-debug build
 
 Specify what Xen should do in the event of an NMI parity or I/O error.
 `ignore` discards the error; `dom0` causes Xen to report the error to
@@ -1171,7 +1174,12 @@ Flag to enable Supervisor Mode Execution Protection
 Flag to enable Supervisor Mode Access Prevention
 
 ### snb\_igd\_quirk
-> `= <boolean>`
+> `= <boolean> | cap | <integer>`
+
+A true boolean value enables legacy behavior (1s timeout), while `cap`
+enforces the maximum theoretically necessary timeout of 670ms. Any number
+is being interpreted as a custom timeout in milliseconds. Zero or boolean
+false disable the quirk workaround, which is also the default.
 
 ### sync\_console
 > `= <boolean>`
diff --git a/m4/systemd.m4 b/m4/systemd.m4
index a832d59..b04964b 100644
--- a/m4/systemd.m4
+++ b/m4/systemd.m4
@@ -42,13 +42,6 @@ AC_DEFUN([AX_ALLOW_SYSTEMD_OPTS], [
 ])
 
 AC_DEFUN([AX_CHECK_SYSTEMD_LIBS], [
-	AC_CHECK_HEADER([systemd/sd-daemon.h], [
-	    AC_CHECK_LIB([systemd-daemon], [sd_listen_fds], [libsystemddaemon="y"])
-	])
-	AS_IF([test "x$libsystemddaemon" = x], [
-	    AC_MSG_ERROR([Unable to find a suitable libsystemd-daemon library])
-	])
-
 	PKG_CHECK_MODULES([SYSTEMD], [libsystemd-daemon])
 	dnl pkg-config older than 0.24 does not set these for
 	dnl PKG_CHECK_MODULES() worth also noting is that as of version 208
@@ -98,9 +91,8 @@ AC_DEFUN([AX_CHECK_SYSTEMD], [
 ])
 
 AC_DEFUN([AX_CHECK_SYSTEMD_ENABLE_AVAILABLE], [
-	AC_CHECK_HEADER([systemd/sd-daemon.h], [
-	    AC_CHECK_LIB([systemd-daemon], [sd_listen_fds], [systemd="y"])
-	])
+	PKG_CHECK_MODULES([SYSTEMD], [libsystemd-daemon], [systemd="y"],
+                          [systemd="n"])
 ])
 
 dnl Enables systemd by default and requires a --disable-systemd option flag
diff --git a/tools/configure b/tools/configure
index c65ad3a..b0aea0a 100755
--- a/tools/configure
+++ b/tools/configure
@@ -8663,116 +8663,87 @@ fi
 
 
 
-	ac_fn_c_check_header_mongrel "$LINENO" "systemd/sd-daemon.h" "ac_cv_header_systemd_sd_daemon_h" "$ac_includes_default"
-if test "x$ac_cv_header_systemd_sd_daemon_h" = xyes; then :
 
-	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sd_listen_fds in -lsystemd-daemon" >&5
-$as_echo_n "checking for sd_listen_fds in -lsystemd-daemon... " >&6; }
-if ${ac_cv_lib_systemd_daemon_sd_listen_fds+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lsystemd-daemon  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SYSTEMD" >&5
+$as_echo_n "checking for SYSTEMD... " >&6; }
 
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char sd_listen_fds ();
-int
-main ()
-{
-return sd_listen_fds ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_systemd_daemon_sd_listen_fds=yes
+if test -n "$SYSTEMD_CFLAGS"; then
+    pkg_cv_SYSTEMD_CFLAGS="$SYSTEMD_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd-daemon\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libsystemd-daemon") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_SYSTEMD_CFLAGS=`$PKG_CONFIG --cflags "libsystemd-daemon" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
-  ac_cv_lib_systemd_daemon_sd_listen_fds=no
+  pkg_failed=yes
 fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+ else
+    pkg_failed=untried
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_systemd_daemon_sd_listen_fds" >&5
-$as_echo "$ac_cv_lib_systemd_daemon_sd_listen_fds" >&6; }
-if test "x$ac_cv_lib_systemd_daemon_sd_listen_fds" = xyes; then :
-  systemd="y"
+if test -n "$SYSTEMD_LIBS"; then
+    pkg_cv_SYSTEMD_LIBS="$SYSTEMD_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd-daemon\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libsystemd-daemon") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_SYSTEMD_LIBS=`$PKG_CONFIG --libs "libsystemd-daemon" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
 fi
-
-
+ else
+    pkg_failed=untried
 fi
 
 
 
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 
-		if test "x$enable_systemd" != "xno"; then :
-
-	     if test "x$systemd" = "xy" ; then :
-
-
-$as_echo "#define HAVE_SYSTEMD 1" >>confdefs.h
-
-			systemd=y
-
-	ac_fn_c_check_header_mongrel "$LINENO" "systemd/sd-daemon.h" "ac_cv_header_systemd_sd_daemon_h" "$ac_includes_default"
-if test "x$ac_cv_header_systemd_sd_daemon_h" = xyes; then :
-
-	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sd_listen_fds in -lsystemd-daemon" >&5
-$as_echo_n "checking for sd_listen_fds in -lsystemd-daemon... " >&6; }
-if ${ac_cv_lib_systemd_daemon_sd_listen_fds+:} false; then :
-  $as_echo_n "(cached) " >&6
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
 else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lsystemd-daemon  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        SYSTEMD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsystemd-daemon" 2>&1`
+        else
+	        SYSTEMD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsystemd-daemon" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$SYSTEMD_PKG_ERRORS" >&5
 
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char sd_listen_fds ();
-int
-main ()
-{
-return sd_listen_fds ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_systemd_daemon_sd_listen_fds=yes
+	systemd="n"
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	systemd="n"
 else
-  ac_cv_lib_systemd_daemon_sd_listen_fds=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_systemd_daemon_sd_listen_fds" >&5
-$as_echo "$ac_cv_lib_systemd_daemon_sd_listen_fds" >&6; }
-if test "x$ac_cv_lib_systemd_daemon_sd_listen_fds" = xyes; then :
-  libsystemddaemon="y"
+	SYSTEMD_CFLAGS=$pkg_cv_SYSTEMD_CFLAGS
+	SYSTEMD_LIBS=$pkg_cv_SYSTEMD_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	systemd="y"
 fi
 
 
-fi
+		if test "x$enable_systemd" != "xno"; then :
 
+	     if test "x$systemd" = "xy" ; then :
 
-	if test "x$libsystemddaemon" = x; then :
 
-	    as_fn_error $? "Unable to find a suitable libsystemd-daemon library" "$LINENO" 5
+$as_echo "#define HAVE_SYSTEMD 1" >>confdefs.h
 
-fi
+			systemd=y
 
 
 pkg_failed=no
diff --git a/tools/flask/policy/policy/modules/xen/xen.if b/tools/flask/policy/policy/modules/xen/xen.if
index fa69c9d..2d32e1c 100644
--- a/tools/flask/policy/policy/modules/xen/xen.if
+++ b/tools/flask/policy/policy/modules/xen/xen.if
@@ -48,11 +48,13 @@ define(`create_domain_common', `
 	allow $1 $2:domain { create max_vcpus setdomainmaxmem setaddrsize
 			getdomaininfo hypercall setvcpucontext setextvcpucontext
 			getscheduler getvcpuinfo getvcpuextstate getaddrsize
-			getaffinity setaffinity };
-	allow $1 $2:domain2 { set_cpuid settsc setscheduler setclaim set_max_evtchn set_vnumainfo get_vnumainfo psr_cmt_op configure_domain };
+			getaffinity setaffinity setvcpuextstate };
+	allow $1 $2:domain2 { set_cpuid settsc setscheduler setclaim
+			set_max_evtchn set_vnumainfo get_vnumainfo cacheflush
+			psr_cmt_op configure_domain };
 	allow $1 $2:security check_context;
 	allow $1 $2:shadow enable;
-	allow $1 $2:mmu { map_read map_write adjust memorymap physmap pinpage mmuext_op };
+	allow $1 $2:mmu { map_read map_write adjust memorymap physmap pinpage mmuext_op updatemp };
 	allow $1 $2:grant setup;
 	allow $1 $2:hvm { cacheattr getparam hvmctl irqlevel pciroute sethvmc
 			setparam pcilevel trackdirtyvram nested };
@@ -80,7 +82,7 @@ define(`create_domain_build_label', `
 define(`manage_domain', `
 	allow $1 $2:domain { getdomaininfo getvcpuinfo getaffinity
 			getaddrsize pause unpause trigger shutdown destroy
-			setaffinity setdomainmaxmem getscheduler };
+			setaffinity setdomainmaxmem getscheduler resume };
     allow $1 $2:domain2 set_vnumainfo;
 ')
 
@@ -88,6 +90,7 @@ define(`manage_domain', `
 #   Allow creation of a snapshot or migration image from a domain
 #   (inbound migration is the same as domain creation)
 define(`migrate_domain_out', `
+	allow $1 domxen_t:mmu map_read;
 	allow $1 $2:hvm { gethvmc getparam irqlevel };
 	allow $1 $2:mmu { stat pageinfo map_read };
 	allow $1 $2:domain { getaddrsize getvcpucontext getextvcpucontext getvcpuextstate pause destroy };
diff --git a/tools/flask/policy/policy/modules/xen/xen.te b/tools/flask/policy/policy/modules/xen/xen.te
index d214470..c0128aa 100644
--- a/tools/flask/policy/policy/modules/xen/xen.te
+++ b/tools/flask/policy/policy/modules/xen/xen.te
@@ -129,12 +129,14 @@ create_domain(dom0_t, domU_t)
 manage_domain(dom0_t, domU_t)
 domain_comms(dom0_t, domU_t)
 domain_comms(domU_t, domU_t)
+migrate_domain_out(dom0_t, domU_t)
 domain_self_comms(domU_t)
 
 declare_domain(isolated_domU_t)
 create_domain(dom0_t, isolated_domU_t)
 manage_domain(dom0_t, isolated_domU_t)
 domain_comms(dom0_t, isolated_domU_t)
+migrate_domain_out(dom0_t, isolated_domU_t)
 domain_self_comms(isolated_domU_t)
 
 # Declare a boolean that denies creation of prot_domU_t domains
@@ -142,6 +144,7 @@ gen_bool(prot_doms_locked, false)
 declare_domain(prot_domU_t)
 if (!prot_doms_locked) {
 	create_domain(dom0_t, prot_domU_t)
+	migrate_domain_out(dom0_t, prot_domU_t)
 }
 domain_comms(dom0_t, prot_domU_t)
 domain_comms(domU_t, prot_domU_t)
diff --git a/tools/hotplug/Linux/systemd/var-lib-xenstored.mount.in b/tools/hotplug/Linux/systemd/var-lib-xenstored.mount.in
index d5e04db..11a7d50 100644
--- a/tools/hotplug/Linux/systemd/var-lib-xenstored.mount.in
+++ b/tools/hotplug/Linux/systemd/var-lib-xenstored.mount.in
@@ -6,9 +6,7 @@ ConditionPathExists=/proc/xen/capabilities
 RefuseManualStop=true
 
 [Mount]
-Environment=XENSTORED_MOUNT_CTX=none
-EnvironmentFile=- at CONFIG_DIR@/@CONFIG_LEAF_DIR@/xenstored
 What=xenstore
 Where=@XEN_LIB_STORED@
 Type=tmpfs
-Options=mode=755,context="$XENSTORED_MOUNT_CTX"
+Options=mode=755
diff --git a/tools/hotplug/Linux/systemd/xen-init-dom0.service.in b/tools/hotplug/Linux/systemd/xen-init-dom0.service.in
index 4d4cb23..3befadc 100644
--- a/tools/hotplug/Linux/systemd/xen-init-dom0.service.in
+++ b/tools/hotplug/Linux/systemd/xen-init-dom0.service.in
@@ -1,7 +1,7 @@
 [Unit]
 Description=xen-init-dom0, initialise Dom0 configuration (xenstore nodes, JSON configuration stub)
-Requires=xenstored.socket proc-xen.mount
-After=xenstored.socket proc-xen.mount
+Requires=xenstored.service proc-xen.mount
+After=xenstored.service proc-xen.mount
 ConditionPathExists=/proc/xen/capabilities
 
 [Service]
diff --git a/tools/hotplug/Linux/systemd/xen-qemu-dom0-disk-backend.service.in b/tools/hotplug/Linux/systemd/xen-qemu-dom0-disk-backend.service.in
index 6b9c96e..274cec0 100644
--- a/tools/hotplug/Linux/systemd/xen-qemu-dom0-disk-backend.service.in
+++ b/tools/hotplug/Linux/systemd/xen-qemu-dom0-disk-backend.service.in
@@ -1,14 +1,13 @@
 [Unit]
 Description=qemu for xen dom0 disk backend
-Requires=proc-xen.mount xenstored.socket
-After=proc-xen.mount xenstored.socket xenconsoled.service
+Requires=proc-xen.mount xenstored.service
+After=proc-xen.mount xenstored.service xenconsoled.service
 Before=xendomains.service libvirtd.service libvirt-guests.service
 RefuseManualStop=true
 ConditionPathExists=/proc/xen/capabilities
 
 [Service]
 Type=simple
-EnvironmentFile=- at CONFIG_DIR@/@CONFIG_LEAF_DIR@/xenstored
 PIDFile=@XEN_RUN_DIR@/qemu-dom0.pid
 ExecStartPre=/bin/grep -q control_d /proc/xen/capabilities
 ExecStartPre=/bin/mkdir -p @XEN_RUN_DIR@
diff --git a/tools/hotplug/Linux/systemd/xenconsoled.service.in b/tools/hotplug/Linux/systemd/xenconsoled.service.in
index 2c5d99f..cd282bf 100644
--- a/tools/hotplug/Linux/systemd/xenconsoled.service.in
+++ b/tools/hotplug/Linux/systemd/xenconsoled.service.in
@@ -1,19 +1,19 @@
 [Unit]
 Description=Xenconsoled - handles logging from guest consoles and hypervisor
-Requires=proc-xen.mount xenstored.socket
-After=proc-xen.mount xenstored.socket
+Requires=proc-xen.mount xenstored.service
+After=proc-xen.mount xenstored.service
 ConditionPathExists=/proc/xen/capabilities
 
 [Service]
 Type=simple
 Environment=XENCONSOLED_ARGS=
-Environment=XENCONSOLED_LOG=none
+Environment=XENCONSOLED_TRACE=none
 Environment=XENCONSOLED_LOG_DIR=@XEN_LOG_DIR@/console
-EnvironmentFile=- at CONFIG_DIR@/@CONFIG_LEAF_DIR@/xenconsoled
+EnvironmentFile=@CONFIG_DIR@/@CONFIG_LEAF_DIR@/xencommons
 PIDFile=@XEN_RUN_DIR@/xenconsoled.pid
 ExecStartPre=/bin/grep -q control_d /proc/xen/capabilities
 ExecStartPre=/bin/mkdir -p ${XENCONSOLED_LOG_DIR}
-ExecStart=@sbindir@/xenconsoled --pid-file @XEN_RUN_DIR@/xenconsoled.pid --log=${XENCONSOLED_LOG} --log-dir=${XENCONSOLED_LOG_DIR} $XENCONSOLED_ARGS
+ExecStart=@sbindir@/xenconsoled --pid-file @XEN_RUN_DIR@/xenconsoled.pid --log=${XENCONSOLED_TRACE} --log-dir=${XENCONSOLED_LOG_DIR} $XENCONSOLED_ARGS
 
 [Install]
 WantedBy=multi-user.target
diff --git a/tools/hotplug/Linux/systemd/xendomains.service.in b/tools/hotplug/Linux/systemd/xendomains.service.in
index 757278f..66e2065 100644
--- a/tools/hotplug/Linux/systemd/xendomains.service.in
+++ b/tools/hotplug/Linux/systemd/xendomains.service.in
@@ -1,7 +1,9 @@
 [Unit]
 Description=Xendomains - start and stop guests on boot and shutdown
-Requires=proc-xen.mount xenstored.socket
-After=proc-xen.mount xenstored.socket xenconsoled.service xen-init-dom0.service
+Requires=proc-xen.mount xenstored.service
+After=proc-xen.mount xenstored.service xenconsoled.service xen-init-dom0.service
+After=network-online.target
+After=remote-fs.target
 ConditionPathExists=/proc/xen/capabilities
 
 [Service]
diff --git a/tools/hotplug/Linux/systemd/xenstored.service.in b/tools/hotplug/Linux/systemd/xenstored.service.in
index 780bdd6..0f0ac58 100644
--- a/tools/hotplug/Linux/systemd/xenstored.service.in
+++ b/tools/hotplug/Linux/systemd/xenstored.service.in
@@ -9,7 +9,6 @@ ConditionPathExists=/proc/xen/capabilities
 [Service]
 Type=notify
 Environment=XENSTORED_ARGS=
-Environment=XENSTORED_ROOTDIR=@XEN_LIB_STORED@
 Environment=XENSTORED=@XENSTORED@
 EnvironmentFile=- at CONFIG_DIR@/@CONFIG_LEAF_DIR@/xencommons
 ExecStartPre=/bin/grep -q control_d /proc/xen/capabilities
diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c
index d8bd9b3..a382701 100644
--- a/tools/libxc/xc_domain_restore.c
+++ b/tools/libxc/xc_domain_restore.c
@@ -1404,7 +1404,7 @@ static int apply_batch(xc_interface *xch, uint32_t dom, struct restore_ctx *ctx,
                 int v;
 
                 DPRINTF("************** pfn=%lx type=%lx gotcs=%08lx "
-                        "actualcs=%08lx\n", pfn, pagebuf->pfn_types[pfn],
+                        "actualcs=%08lx\n", pfn, pfn_type[pfn],
                         csum_page(region_base + i * PAGE_SIZE),
                         csum_page(buf));
 
diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c
index 1c214dd..e2441ad 100644
--- a/tools/libxc/xc_private.c
+++ b/tools/libxc/xc_private.c
@@ -613,8 +613,10 @@ int xc_get_pfn_list(xc_interface *xch,
 long xc_get_tot_pages(xc_interface *xch, uint32_t domid)
 {
     xc_dominfo_t info;
-    return (xc_domain_getinfo(xch, domid, 1, &info) != 1) ?
-        -1 : info.nr_pages;
+    if ( (xc_domain_getinfo(xch, domid, 1, &info) != 1) ||
+         (info.domid != domid) )
+        return -1;
+    return info.nr_pages;
 }
 
 int xc_copy_to_domain_page(xc_interface *xch,
diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
index df08c8a..b417372 100644
--- a/tools/libxl/Makefile
+++ b/tools/libxl/Makefile
@@ -41,7 +41,7 @@ LDFLAGS += $(PTHREAD_LDFLAGS)
 LIBXL_LIBS += $(PTHREAD_LIBS)
 LIBXL_LIBS += $(LIBXL_LIBS-y)
 
-LIBXLU_LIBS =
+LIBXLU_LIBS = libxenlight.so
 
 LIBXL_OBJS-y = osdeps.o libxl_paths.o libxl_bootloader.o flexarray.o
 ifeq ($(LIBXL_BLKTAP),y)
@@ -227,8 +227,8 @@ libxlutil.so: libxlutil.so.$(XLUMAJOR)
 libxlutil.so.$(XLUMAJOR): libxlutil.so.$(XLUMAJOR).$(XLUMINOR)
 	$(SYMLINK_SHLIB) $< $@
 
-libxlutil.so.$(XLUMAJOR).$(XLUMINOR): $(LIBXLU_OBJS)
-	$(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxlutil.so.$(XLUMAJOR) $(SHLIB_LDFLAGS) -o $@ $^ $(LIBXLU_LIBS) $(APPEND_LDFLAGS)
+libxlutil.so.$(XLUMAJOR).$(XLUMINOR): $(LIBXLU_OBJS) libxenlight.so
+	$(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxlutil.so.$(XLUMAJOR) $(SHLIB_LDFLAGS) -o $@ $(LIBXLU_OBJS) $(LIBXLU_LIBS) $(APPEND_LDFLAGS)
 
 libxlutil.a: $(LIBXLU_OBJS)
 	$(AR) rcs libxlutil.a $^
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index f84f7c2..372dd3b 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -118,8 +118,6 @@ int libxl_ctx_alloc(libxl_ctx **pctx, int version,
         rc = ERROR_FAIL; goto out;
     }
 
-    rc = libxl__ctx_evtchn_init(gc);
-
     *pctx = ctx;
     return 0;
 
@@ -148,6 +146,8 @@ int libxl_ctx_free(libxl_ctx *ctx)
 {
     if (!ctx) return 0;
 
+    assert(!ctx->osevent_in_hook);
+
     int i;
     GC_INIT(ctx);
 
@@ -160,11 +160,12 @@ int libxl_ctx_free(libxl_ctx *ctx)
     while ((eject = LIBXL_LIST_FIRST(&CTX->disk_eject_evgens)))
         libxl__evdisable_disk_eject(gc, eject);
 
+    libxl_childproc_setmode(CTX,0,0);
     for (i = 0; i < ctx->watch_nslots; i++)
         assert(!libxl__watch_slot_contents(gc, i));
-    libxl__ev_fd_deregister(gc, &ctx->watch_efd);
-    libxl__ev_fd_deregister(gc, &ctx->evtchn_efd);
-    libxl__ev_fd_deregister(gc, &ctx->sigchld_selfpipe_efd);
+    assert(!libxl__ev_fd_isregistered(&ctx->watch_efd));
+    assert(!libxl__ev_fd_isregistered(&ctx->evtchn_efd));
+    assert(!libxl__ev_fd_isregistered(&ctx->sigchld_selfpipe_efd));
 
     /* Now there should be no more events requested from the application: */
 
@@ -363,6 +364,8 @@ int libxl__domain_rename(libxl__gc *gc, uint32_t domid,
     char *uuid;
     const char *vm_name_path;
 
+    libxl_dominfo_init(&info);
+
     dom_path = libxl__xs_get_dompath(gc, domid);
     if (!dom_path) goto x_nomem;
 
@@ -385,6 +388,13 @@ int libxl__domain_rename(libxl__gc *gc, uint32_t domid,
         }
     }
 
+    if (!new_name) {
+        LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
+                        "new domain name not specified");
+        rc = ERROR_INVAL;
+        goto x_rc;
+    }
+
     if (new_name[0]) {
         /* nonempty names must be unique */
         uint32_t domid_e;
@@ -473,6 +483,7 @@ int libxl__domain_rename(libxl__gc *gc, uint32_t domid,
     rc = 0;
  x_rc:
     if (our_trans) xs_transaction_end(ctx->xsh, our_trans, 1);
+    libxl_dominfo_dispose(&info);
     return rc;
 
  x_fail:  rc = ERROR_FAIL;  goto x_rc;
@@ -674,7 +685,7 @@ int libxl_domain_info(libxl_ctx *ctx, libxl_dominfo *info_r,
 
     ret = xc_domain_getinfolist(ctx->xch, domid, 1, &xcinfo);
     if (ret<0) {
-        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "geting domain info list");
+        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting domain info list");
         return ERROR_FAIL;
     }
     if (ret==0 || xcinfo.domain != domid) return ERROR_INVAL;
@@ -4586,6 +4597,8 @@ static int libxl__fill_dom0_memory_info(libxl__gc *gc, uint32_t *target_memkb,
     libxl_ctx *ctx = libxl__gc_owner(gc);
     uint32_t free_mem_slack_kb = 0;
 
+    libxl_dominfo_init(&info);
+
 retry_transaction:
     t = xs_transaction_start(ctx->xsh);
 
@@ -4618,6 +4631,8 @@ retry_transaction:
         }
     }
 
+    libxl_dominfo_dispose(&info);
+    libxl_dominfo_init(&info);
     rc = libxl_domain_info(ctx, &info, 0);
     if (rc < 0)
         goto out;
@@ -4656,7 +4671,7 @@ out:
             rc = ERROR_FAIL;
     }
 
-
+    libxl_dominfo_dispose(&info);
     return rc;
 }
 
@@ -4991,6 +5006,8 @@ int libxl_wait_for_memory_target(libxl_ctx *ctx, uint32_t domid, int wait_secs)
     uint32_t target_memkb = 0;
     libxl_dominfo info;
 
+    libxl_dominfo_init(&info);
+
     do {
         wait_secs--;
         sleep(1);
@@ -4999,9 +5016,11 @@ int libxl_wait_for_memory_target(libxl_ctx *ctx, uint32_t domid, int wait_secs)
         if (rc < 0)
             goto out;
 
+        libxl_dominfo_dispose(&info);
+        libxl_dominfo_init(&info);
         rc = libxl_domain_info(ctx, &info, domid);
         if (rc < 0)
-            return rc;
+            goto out;
     } while (wait_secs > 0 && (info.current_memkb + info.outstanding_memkb) > target_memkb);
 
     if ((info.current_memkb + info.outstanding_memkb) <= target_memkb)
@@ -5010,6 +5029,7 @@ int libxl_wait_for_memory_target(libxl_ctx *ctx, uint32_t domid, int wait_secs)
         rc = ERROR_FAIL;
 
 out:
+    libxl_dominfo_dispose(&info);
     return rc;
 }
 
@@ -5427,6 +5447,8 @@ static int libxl__set_vcpuonline_xenstore(libxl__gc *gc, uint32_t domid,
     xs_transaction_t t;
     int i, rc = ERROR_FAIL;
 
+    libxl_dominfo_init(&info);
+
     if (libxl_domain_info(CTX, &info, domid) < 0) {
         LOGE(ERROR, "getting domain info list");
         goto out;
@@ -5446,6 +5468,7 @@ retry_transaction:
     } else
         rc = 0;
 out:
+    libxl_dominfo_dispose(&info);
     return rc;
 }
 
@@ -5455,8 +5478,11 @@ static int libxl__set_vcpuonline_qmp(libxl__gc *gc, uint32_t domid,
     libxl_dominfo info;
     int i;
 
+    libxl_dominfo_init(&info);
+
     if (libxl_domain_info(CTX, &info, domid) < 0) {
         LOGE(ERROR, "getting domain info list");
+        libxl_dominfo_dispose(&info);
         return ERROR_FAIL;
     }
     for (i = 0; i <= info.vcpu_max_id; i++) {
@@ -5469,6 +5495,7 @@ static int libxl__set_vcpuonline_qmp(libxl__gc *gc, uint32_t domid,
             libxl__qmp_cpu_add(gc, domid, i);
         }
     }
+    libxl_dominfo_dispose(&info);
     return 0;
 }
 
@@ -6561,12 +6588,15 @@ int libxl_retrieve_domain_configuration(libxl_ctx *ctx, uint32_t domid,
     /* Domain UUID */
     {
         libxl_dominfo info;
+        libxl_dominfo_init(&info);
         rc = libxl_domain_info(ctx, &info, domid);
         if (rc) {
             LOG(ERROR, "fail to get domain info for domain %d", domid);
+            libxl_dominfo_dispose(&info);
             goto out;
         }
         libxl_uuid_copy(ctx, &d_config->c_info.uuid, &info.uuid);
+        libxl_dominfo_dispose(&info);
     }
 
     /* Memory limits:
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 41d6e8d..0a123f1 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -478,6 +478,16 @@ typedef struct libxl__ctx libxl_ctx;
 #endif
 
 /*
+ * LIBXL_HAVE_NONCONST_LIBXL_BASENAME_RETURN_VALUE
+ *
+ * The return value of libxl_basename is malloc'ed but the erroneously
+ * marked as "const" in releases before 4.5.
+ */
+#if !defined(LIBXL_API_VERSION) || LIBXL_API_VERSION >= 0x040500
+#define LIBXL_HAVE_NONCONST_LIBXL_BASENAME_RETURN_VALUE 1
+#endif
+
+/*
  * LIBXL_HAVE_PHYSINFO_OUTSTANDING_PAGES
  *
  * If this is defined, libxl_physinfo structure will contain an uint64 field
diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index 3e191c3..c2b0487 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -527,6 +527,15 @@ static char ** libxl__build_device_model_args_new(libxl__gc *gc,
     if (b_info->type == LIBXL_DOMAIN_TYPE_HVM) {
         int ioemu_nics = 0;
 
+        if (b_info->kernel)
+            flexarray_vappend(dm_args, "-kernel", b_info->kernel, NULL);
+
+        if (b_info->ramdisk)
+            flexarray_vappend(dm_args, "-initrd", b_info->ramdisk, NULL);
+
+        if (b_info->cmdline)
+            flexarray_vappend(dm_args, "-append", b_info->cmdline, NULL);
+
         if (b_info->u.hvm.serial || b_info->u.hvm.serial_list) {
             if ( b_info->u.hvm.serial && b_info->u.hvm.serial_list )
             {
@@ -788,11 +797,13 @@ static char ** libxl__build_device_model_args_new(libxl__gc *gc,
                     continue;
                 }
 
-                if (disks[i].backend == LIBXL_DISK_BACKEND_TAP)
+                if (disks[i].backend == LIBXL_DISK_BACKEND_TAP) {
+                    format = qemu_disk_format_string(LIBXL_DISK_FORMAT_RAW);
                     pdev_path = libxl__blktap_devpath(gc, disks[i].pdev_path,
                                                       disks[i].format);
-                else
+                } else {
                     pdev_path = disks[i].pdev_path;
+                }
 
                 /*
                  * Explicit sd disks are passed through as is.
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index 74ea84b..1d33a18 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -1824,6 +1824,9 @@ void libxl__domain_suspend(libxl__egc *egc, libxl__domain_suspend_state *dss)
     port = xs_suspend_evtchn_port(dss->domid);
 
     if (port >= 0) {
+        rc = libxl__ctx_evtchn_init(gc);
+        if (rc) goto out;
+
         dss->guest_evtchn.port =
             xc_suspend_evtchn_init_exclusive(CTX->xch, CTX->xce,
                                   dss->domid, port, &dss->guest_evtchn_lockfd);
@@ -2043,19 +2046,25 @@ const char *libxl__userdata_path(libxl__gc *gc, uint32_t domid,
                                  const char *wh)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
-    char *uuid_string;
+    char *uuid_string, *path;
     libxl_dominfo info;
     int rc;
 
+    libxl_dominfo_init(&info);
+
     rc = libxl_domain_info(ctx, &info, domid);
     if (rc) {
         LOGE(ERROR, "unable to find domain info for domain %"PRIu32, domid);
-        return NULL;
+        path = NULL;
+        goto out;
     }
     uuid_string = GCSPRINTF(LIBXL_UUID_FMT, LIBXL_UUID_BYTES(info.uuid));
-
-    return GCSPRINTF("/var/lib/xen/userdata-%s.%u.%s.%s",
+    path = GCSPRINTF("/var/lib/xen/userdata-%s.%u.%s.%s",
                      wh, domid, uuid_string, userdata_userid);
+
+ out:
+    libxl_dominfo_dispose(&info);
+    return path;
 }
 
 static int userdata_delete(libxl__gc *gc, const char *path)
diff --git a/tools/libxl/libxl_event.c b/tools/libxl/libxl_event.c
index 22b1227..0d874d9 100644
--- a/tools/libxl/libxl_event.c
+++ b/tools/libxl/libxl_event.c
@@ -524,6 +524,13 @@ static char *watch_token(libxl__gc *gc, int slotnum, uint32_t counterval)
     return libxl__sprintf(gc, "%d/%"PRIx32, slotnum, counterval);
 }
 
+static void watches_check_fd_deregister(libxl__gc *gc)
+{
+    assert(CTX->nwatches>=0);
+    if (!CTX->nwatches)
+        libxl__ev_fd_deregister(gc, &CTX->watch_efd);
+}
+
 int libxl__ev_xswatch_register(libxl__gc *gc, libxl__ev_xswatch *w,
                                libxl__ev_xswatch_callback *func,
                                const char *path /* copied */)
@@ -579,6 +586,7 @@ int libxl__ev_xswatch_register(libxl__gc *gc, libxl__ev_xswatch *w,
     w->slotnum = slotnum;
     w->path = path_copy;
     w->callback = func;
+    CTX->nwatches++;
     libxl__set_watch_slot_contents(use, w);
 
     CTX_UNLOCK;
@@ -590,6 +598,7 @@ int libxl__ev_xswatch_register(libxl__gc *gc, libxl__ev_xswatch *w,
     if (use)
         LIBXL_SLIST_INSERT_HEAD(&CTX->watch_freeslots, use, empty);
     free(path_copy);
+    watches_check_fd_deregister(gc);
     CTX_UNLOCK;
     return rc;
 }
@@ -614,6 +623,8 @@ void libxl__ev_xswatch_deregister(libxl__gc *gc, libxl__ev_xswatch *w)
         libxl__ev_watch_slot *slot = &CTX->watch_slots[w->slotnum];
         LIBXL_SLIST_INSERT_HEAD(&CTX->watch_freeslots, slot, empty);
         w->slotnum = -1;
+        CTX->nwatches--;
+        watches_check_fd_deregister(gc);
     } else {
         LOG(DEBUG, "watch w=%p: deregister unregistered", w);
     }
@@ -728,10 +739,6 @@ int libxl__ctx_evtchn_init(libxl__gc *gc) {
     rc = libxl_fd_set_nonblock(CTX, fd, 1);
     if (rc) goto out;
 
-    rc = libxl__ev_fd_register(gc, &CTX->evtchn_efd,
-                               evtchn_fd_callback, fd, POLLIN);
-    if (rc) goto out;
-
     CTX->xce = xce;
     return 0;
 
@@ -740,6 +747,12 @@ int libxl__ctx_evtchn_init(libxl__gc *gc) {
     return rc;
 }
 
+static void evtchn_check_fd_deregister(libxl__gc *gc)
+{
+    if (CTX->xce && LIBXL_LIST_EMPTY(&CTX->evtchns_waiting))
+        libxl__ev_fd_deregister(gc, &CTX->evtchn_efd);
+}
+
 int libxl__ev_evtchn_wait(libxl__gc *gc, libxl__ev_evtchn *evev)
 {
     int r, rc;
@@ -747,6 +760,15 @@ int libxl__ev_evtchn_wait(libxl__gc *gc, libxl__ev_evtchn *evev)
     DBG("ev_evtchn=%p port=%d wait (was waiting=%d)",
         evev, evev->port, evev->waiting);
 
+    rc = libxl__ctx_evtchn_init(gc);
+    if (rc) goto out;
+
+    if (!libxl__ev_fd_isregistered(&CTX->evtchn_efd)) {
+        rc = libxl__ev_fd_register(gc, &CTX->evtchn_efd, evtchn_fd_callback,
+                                   xc_evtchn_fd(CTX->xce), POLLIN);
+        if (rc) goto out;
+    }
+
     if (evev->waiting)
         return 0;
 
@@ -762,6 +784,7 @@ int libxl__ev_evtchn_wait(libxl__gc *gc, libxl__ev_evtchn *evev)
     return 0;
 
  out:
+    evtchn_check_fd_deregister(gc);
     return rc;
 }
 
@@ -775,6 +798,7 @@ void libxl__ev_evtchn_cancel(libxl__gc *gc, libxl__ev_evtchn *evev)
 
     evev->waiting = 0;
     LIBXL_LIST_REMOVE(evev, entry);
+    evtchn_check_fd_deregister(gc);
 }
 
 /*
@@ -1195,6 +1219,8 @@ void libxl_osevent_register_hooks(libxl_ctx *ctx,
 {
     GC_INIT(ctx);
     CTX_LOCK;
+    assert(LIBXL_LIST_EMPTY(&ctx->efds));
+    assert(LIBXL_TAILQ_EMPTY(&ctx->etimes));
     ctx->osevent_hooks = hooks;
     ctx->osevent_user = user;
     CTX_UNLOCK;
diff --git a/tools/libxl/libxl_event.h b/tools/libxl/libxl_event.h
index b5db83c..3c6fcfe 100644
--- a/tools/libxl/libxl_event.h
+++ b/tools/libxl/libxl_event.h
@@ -124,10 +124,8 @@ void libxl_event_register_callbacks(libxl_ctx *ctx,
    * different parameters, as the application likes; the most recent
    * call determines the libxl behaviour.  However it is NOT safe to
    * call _register_callbacks concurrently with, or reentrantly from,
-   * any other libxl function.
-   *
-   * Calls to _register_callbacks do not affect events which have
-   * already occurred.
+   * any other libxl function, nor while any event-generation
+   * facilities are enabled.
    */
 
 
diff --git a/tools/libxl/libxl_fork.c b/tools/libxl/libxl_fork.c
index fa15095..144208a 100644
--- a/tools/libxl/libxl_fork.c
+++ b/tools/libxl/libxl_fork.c
@@ -372,15 +372,8 @@ static void sigchld_user_remove(libxl_ctx *ctx) /* idempotent */
 
 void libxl__sigchld_notneeded(libxl__gc *gc) /* non-reentrant, idempotent */
 {
-    int rc;
-
     sigchld_user_remove(CTX);
-
-    if (libxl__ev_fd_isregistered(&CTX->sigchld_selfpipe_efd)) {
-        rc = libxl__ev_fd_modify(gc, &CTX->sigchld_selfpipe_efd, 0);
-        if (rc)
-            libxl__ev_fd_deregister(gc, &CTX->sigchld_selfpipe_efd);
-    }
+    libxl__ev_fd_deregister(gc, &CTX->sigchld_selfpipe_efd);
 }
 
 int libxl__sigchld_needed(libxl__gc *gc) /* non-reentrant, idempotent */
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index a38f695..6dac0f8 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -352,7 +352,7 @@ struct libxl__ctx {
     LIBXL_TAILQ_HEAD(, libxl__ev_time) etimes;
 
     libxl__ev_watch_slot *watch_slots;
-    int watch_nslots;
+    int watch_nslots, nwatches;
     LIBXL_SLIST_HEAD(, libxl__ev_watch_slot) watch_freeslots;
     uint32_t watch_counter; /* helps disambiguate slot reuse */
     libxl__ev_fd watch_efd;
@@ -800,8 +800,10 @@ static inline int libxl__ev_xswatch_isregistered(const libxl__ev_xswatch *xw)
 
 /*
  * The evtchn facility is one-shot per call to libxl__ev_evtchn_wait.
- * You should call some suitable xc bind function on (or to obtain)
- * the port, then libxl__ev_evtchn_wait.
+ * You should:
+ *   Use libxl__ctx_evtchn_init to make sure CTX->xce is valid;
+ *   Call some suitable xc bind function on (or to obtain) the port;
+ *   Then call libxl__ev_evtchn_wait.
  *
  * When the event is signaled then the callback will be made, once.
  * Then you must call libxl__ev_evtchn_wait again, if desired.
diff --git a/tools/libxl/libxl_pci.c b/tools/libxl/libxl_pci.c
index 316643c..f3ae132 100644
--- a/tools/libxl/libxl_pci.c
+++ b/tools/libxl/libxl_pci.c
@@ -1243,13 +1243,13 @@ static int do_pci_remove(libxl__gc *gc, uint32_t domid,
             rc = ERROR_INVAL;
             goto out_fail;
         }
-        if (rc) {
+        if (rc && !force) {
             rc = ERROR_FAIL;
             goto out_fail;
         }
-    } else if (type != LIBXL_DOMAIN_TYPE_PV)
-        abort();
-    {
+    } else {
+        assert(type == LIBXL_DOMAIN_TYPE_PV);
+
         char *sysfs_path = libxl__sprintf(gc, SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain,
                                          pcidev->bus, pcidev->dev, pcidev->func);
         FILE *f = fopen(sysfs_path, "r");
diff --git a/tools/libxl/libxl_utils.c b/tools/libxl/libxl_utils.c
index 3e1ba17..7095b58 100644
--- a/tools/libxl/libxl_utils.c
+++ b/tools/libxl/libxl_utils.c
@@ -19,7 +19,10 @@
 
 #include "libxl_internal.h"
 
-const char *libxl_basename(const char *name)
+#ifndef LIBXL_HAVE_NONCONST_LIBXL_BASENAME_RETURN_VALUE
+const
+#endif
+char *libxl_basename(const char *name)
 {
     const char *filename;
     if (name == NULL)
diff --git a/tools/libxl/libxl_utils.h b/tools/libxl/libxl_utils.h
index 117b229..acacdd9 100644
--- a/tools/libxl/libxl_utils.h
+++ b/tools/libxl/libxl_utils.h
@@ -18,7 +18,11 @@
 
 #include "libxl.h"
 
-const char *libxl_basename(const char *name); /* returns string from strdup */
+#ifndef LIBXL_HAVE_NONCONST_LIBXL_BASENAME_RETURN_VALUE
+const
+#endif
+char *libxl_basename(const char *name); /* returns string from strdup */
+
 unsigned long libxl_get_required_shadow_memory(unsigned long maxmem_kb, unsigned int smp_cpus);
 int libxl_name_to_domid(libxl_ctx *ctx, const char *name, uint32_t *domid);
 int libxl_domain_qualifier_to_domid(libxl_ctx *ctx, const char *name, uint32_t *domid);
diff --git a/tools/libxl/libxlu_cfg_l.c b/tools/libxl/libxlu_cfg_l.c
index df352aa..450863a 100644
--- a/tools/libxl/libxlu_cfg_l.c
+++ b/tools/libxl/libxlu_cfg_l.c
@@ -610,6 +610,10 @@ int xlu__cfg_yyget_lineno (yyscan_t yyscanner );
 
 void xlu__cfg_yyset_lineno (int line_number ,yyscan_t yyscanner );
 
+int xlu__cfg_yyget_column  (yyscan_t yyscanner );
+
+void xlu__cfg_yyset_column (int column_no ,yyscan_t yyscanner );
+
 YYSTYPE * xlu__cfg_yyget_lval (yyscan_t yyscanner );
 
 void xlu__cfg_yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
@@ -762,7 +766,7 @@ YY_DECL
 #line 53 "libxlu_cfg_l.l"
 
 
-#line 766 "libxlu_cfg_l.c"
+#line 770 "libxlu_cfg_l.c"
 
     yylval = yylval_param;
 
@@ -971,7 +975,7 @@ YY_RULE_SETUP
 #line 104 "libxlu_cfg_l.l"
 YY_FATAL_ERROR( "flex scanner jammed" );
 	YY_BREAK
-#line 975 "libxlu_cfg_l.c"
+#line 979 "libxlu_cfg_l.c"
 case YY_STATE_EOF(INITIAL):
 case YY_STATE_EOF(lexerr):
 	yyterminate();
diff --git a/tools/libxl/libxlu_cfg_l.h b/tools/libxl/libxlu_cfg_l.h
index 4078302..151064e 100644
--- a/tools/libxl/libxlu_cfg_l.h
+++ b/tools/libxl/libxlu_cfg_l.h
@@ -276,6 +276,10 @@ int xlu__cfg_yyget_lineno (yyscan_t yyscanner );
 
 void xlu__cfg_yyset_lineno (int line_number ,yyscan_t yyscanner );
 
+int xlu__cfg_yyget_column  (yyscan_t yyscanner );
+
+void xlu__cfg_yyset_column (int column_no ,yyscan_t yyscanner );
+
 YYSTYPE * xlu__cfg_yyget_lval (yyscan_t yyscanner );
 
 void xlu__cfg_yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
@@ -352,6 +356,6 @@ extern int xlu__cfg_yylex \
 
 #line 104 "libxlu_cfg_l.l"
 
-#line 356 "libxlu_cfg_l.h"
+#line 360 "libxlu_cfg_l.h"
 #undef xlu__cfg_yyIN_HEADER
 #endif /* xlu__cfg_yyHEADER_H */
diff --git a/tools/libxl/libxlu_cfg_y.c b/tools/libxl/libxlu_cfg_y.c
index 4437e05..07b5a1d 100644
--- a/tools/libxl/libxlu_cfg_y.c
+++ b/tools/libxl/libxlu_cfg_y.c
@@ -76,7 +76,7 @@
 /* Line 268 of yacc.c  */
 #line 19 "libxlu_cfg_y.y"
 
-#define YYLEX_PARAM ctx->scanner
+#define ctx_scanner ctx->scanner
 #include "libxlu_cfg_i.h"
 #include "libxlu_cfg_l.h"
 
@@ -656,7 +656,7 @@ while (YYID (0))
 #ifdef YYLEX_PARAM
 # define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
 #else
-# define YYLEX yylex (&yylval, &yylloc, scanner)
+# define YYLEX yylex (&yylval, &yylloc, ctx_scanner)
 #endif
 
 /* Enable debugging if requested.  */
diff --git a/tools/libxl/libxlu_cfg_y.y b/tools/libxl/libxlu_cfg_y.y
index aa9f787..5acd438 100644
--- a/tools/libxl/libxlu_cfg_y.y
+++ b/tools/libxl/libxlu_cfg_y.y
@@ -17,7 +17,7 @@
  */
 
 %{
-#define YYLEX_PARAM ctx->scanner
+#define ctx_scanner ctx->scanner
 #include "libxlu_cfg_i.h"
 #include "libxlu_cfg_l.h"
 %}
@@ -31,9 +31,9 @@
 %pure-parser
 %defines
 %error-verbose
-%name-prefix="xlu__cfg_yy"
+%name-prefix "xlu__cfg_yy"
 %parse-param { CfgParseContext *ctx }
-%lex-param { void *scanner }
+%lex-param { ctx_scanner }
 
 %token <string>                IDENT STRING NUMBER NEWLINE
 %type <string>            atom
diff --git a/tools/libxl/libxlu_disk_l.c b/tools/libxl/libxlu_disk_l.c
index 2c6e8e3..beea7f9 100644
--- a/tools/libxl/libxlu_disk_l.c
+++ b/tools/libxl/libxlu_disk_l.c
@@ -1011,6 +1011,10 @@ int xlu__disk_yyget_lineno (yyscan_t yyscanner );
 
 void xlu__disk_yyset_lineno (int line_number ,yyscan_t yyscanner );
 
+int xlu__disk_yyget_column  (yyscan_t yyscanner );
+
+void xlu__disk_yyset_column (int column_no ,yyscan_t yyscanner );
+
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
  */
@@ -1155,7 +1159,7 @@ YY_DECL
 
  /*----- the scanner rules which do the parsing -----*/
 
-#line 1159 "libxlu_disk_l.c"
+#line 1163 "libxlu_disk_l.c"
 
 	if ( !yyg->yy_init )
 		{
@@ -1498,7 +1502,7 @@ YY_RULE_SETUP
 #line 259 "libxlu_disk_l.l"
 YY_FATAL_ERROR( "flex scanner jammed" );
 	YY_BREAK
-#line 1502 "libxlu_disk_l.c"
+#line 1506 "libxlu_disk_l.c"
 			case YY_STATE_EOF(INITIAL):
 			case YY_STATE_EOF(LEXERR):
 				yyterminate();
diff --git a/tools/libxl/libxlu_disk_l.h b/tools/libxl/libxlu_disk_l.h
index 08f60e5..f615582 100644
--- a/tools/libxl/libxlu_disk_l.h
+++ b/tools/libxl/libxlu_disk_l.h
@@ -280,6 +280,10 @@ int xlu__disk_yyget_lineno (yyscan_t yyscanner );
 
 void xlu__disk_yyset_lineno (int line_number ,yyscan_t yyscanner );
 
+int xlu__disk_yyget_column  (yyscan_t yyscanner );
+
+void xlu__disk_yyset_column (int column_no ,yyscan_t yyscanner );
+
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
  */
@@ -346,6 +350,6 @@ extern int xlu__disk_yylex (yyscan_t yyscanner);
 
 #line 259 "libxlu_disk_l.l"
 
-#line 350 "libxlu_disk_l.h"
+#line 354 "libxlu_disk_l.h"
 #undef xlu__disk_yyIN_HEADER
 #endif /* xlu__disk_yyHEADER_H */
diff --git a/tools/libxl/xl.h b/tools/libxl/xl.h
index c91de4f..5bc138c 100644
--- a/tools/libxl/xl.h
+++ b/tools/libxl/xl.h
@@ -186,7 +186,7 @@ enum output_format {
 };
 extern enum output_format default_output_format;
 
-extern void printf_info_sexp(int domid, libxl_domain_config *d_config);
+extern void printf_info_sexp(int domid, libxl_domain_config *d_config, FILE *fh);
 
 #define XL_GLOBAL_CONFIG XEN_CONFIG_DIR "/xl.conf"
 #define XL_LOCK_FILE XEN_LOCK_DIR "/xl"
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 0e754e7..ed0d478 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -381,10 +381,10 @@ out:
 }
 static void printf_info(enum output_format output_format,
                         int domid,
-                        libxl_domain_config *d_config)
+                        libxl_domain_config *d_config, FILE *fh)
 {
     if (output_format == OUTPUT_FORMAT_SXP)
-        return printf_info_sexp(domid, d_config);
+        return printf_info_sexp(domid, d_config, fh);
 
     const char *buf;
     libxl_yajl_length len = 0;
@@ -405,7 +405,7 @@ static void printf_info(enum output_format output_format,
     if (s != yajl_gen_status_ok)
         goto out;
 
-    puts(buf);
+    fputs(buf, fh);
 
 out:
     yajl_gen_free(hand);
@@ -414,7 +414,13 @@ out:
         fprintf(stderr,
                 "unable to format domain config as JSON (YAJL:%d)\n", s);
 
-    if (ferror(stdout) || fflush(stdout)) { perror("stdout"); exit(-1); }
+    if (ferror(fh) || fflush(fh)) {
+        if (fh == stdout)
+            perror("stdout");
+        else
+            perror("stderr");
+        exit(-1);
+    }
 }
 
 static int do_daemonize(char *name)
@@ -920,6 +926,7 @@ static void parse_config_data(const char *config_source,
     int pci_permissive = 0;
     int pci_seize = 0;
     int i, e;
+    char *kernel_basename;
 
     libxl_domain_create_info *c_info = &d_config->c_info;
     libxl_domain_build_info *b_info = &d_config->b_info;
@@ -1116,13 +1123,15 @@ static void parse_config_data(const char *config_source,
 
     switch(b_info->type) {
     case LIBXL_DOMAIN_TYPE_HVM:
-        if (!strcmp(libxl_basename(b_info->kernel), "hvmloader")) {
+        kernel_basename = libxl_basename(b_info->kernel);
+        if (!strcmp(kernel_basename, "hvmloader")) {
             fprintf(stderr, "WARNING: you seem to be using \"kernel\" "
                     "directive to override HVM guest firmware. Ignore "
                     "that. Use \"firmware_override\" instead if you "
                     "really want a non-default firmware\n");
             b_info->kernel = NULL;
         }
+        free(kernel_basename);
 
         xlu_cfg_replace_string (config, "firmware_override",
                                 &b_info->u.hvm.firmware, 0);
@@ -2436,7 +2445,7 @@ static uint32_t create_domain(struct domain_create *dom_info)
     }
 
     if (!dom_info->quiet)
-        printf("Parsing config from %s\n", config_source);
+        fprintf(stderr, "Parsing config from %s\n", config_source);
 
     if (config_in_json) {
         libxl_domain_config_from_json(ctx, &d_config,
@@ -2464,7 +2473,8 @@ static uint32_t create_domain(struct domain_create *dom_info)
     }
 
     if (debug || dom_info->dryrun)
-        printf_info(default_output_format, -1, &d_config);
+        printf_info(default_output_format, -1, &d_config,
+                    debug ? stderr : stdout);
 
     ret = 0;
     if (dom_info->dryrun)
@@ -3416,7 +3426,7 @@ static void list_domains_details(const libxl_dominfo *info, int nb_domain)
         if (default_output_format == OUTPUT_FORMAT_JSON)
             s = printf_info_one_json(hand, info[i].domid, &d_config);
         else
-            printf_info_sexp(info[i].domid, &d_config);
+            printf_info_sexp(info[i].domid, &d_config, stdout);
         libxl_domain_config_dispose(&d_config);
         if (s != yajl_gen_status_ok)
             goto out;
@@ -4738,7 +4748,7 @@ int main_config_update(int argc, char **argv)
     parse_config_data(filename, config_data, config_len, &d_config);
 
     if (debug || dryrun_only)
-        printf_info(default_output_format, -1, &d_config);
+        printf_info(default_output_format, -1, &d_config, stdout);
 
     if (!dryrun_only) {
         fprintf(stderr, "setting dom%d configuration\n", domid);
@@ -7023,7 +7033,7 @@ int main_cpupoolcreate(int argc, char **argv)
     int config_len = 0;
     XLU_Config *config;
     const char *buf;
-    const char *name;
+    char *name = NULL;
     uint32_t poolid;
     libxl_scheduler sched = 0;
     XLU_ConfigList *cpus;
@@ -7197,6 +7207,7 @@ int main_cpupoolcreate(int argc, char **argv)
 out_cfg:
     xlu_cfg_destroy(config);
 out:
+    free(name);
     free(config_data);
     return rc;
 }
diff --git a/tools/libxl/xl_sxp.c b/tools/libxl/xl_sxp.c
index 1c98352..a8c127b 100644
--- a/tools/libxl/xl_sxp.c
+++ b/tools/libxl/xl_sxp.c
@@ -30,7 +30,7 @@
 /* In general you should not add new output to this function since it
  * is intended only for legacy use.
  */
-void printf_info_sexp(int domid, libxl_domain_config *d_config)
+void printf_info_sexp(int domid, libxl_domain_config *d_config, FILE *fh)
 {
     int i;
     libxl_dominfo info;
@@ -38,195 +38,195 @@ void printf_info_sexp(int domid, libxl_domain_config *d_config)
     libxl_domain_create_info *c_info = &d_config->c_info;
     libxl_domain_build_info *b_info = &d_config->b_info;
 
-    printf("(domain\n\t(domid %d)\n", domid);
-    printf("\t(create_info)\n");
-    printf("\t(hvm %d)\n", c_info->type == LIBXL_DOMAIN_TYPE_HVM);
-    printf("\t(hap %s)\n", libxl_defbool_to_string(c_info->hap));
-    printf("\t(oos %s)\n", libxl_defbool_to_string(c_info->oos));
-    printf("\t(ssidref %d)\n", c_info->ssidref);
-    printf("\t(name %s)\n", c_info->name);
+    fprintf(fh, "(domain\n\t(domid %d)\n", domid);
+    fprintf(fh, "\t(create_info)\n");
+    fprintf(fh, "\t(hvm %d)\n", c_info->type == LIBXL_DOMAIN_TYPE_HVM);
+    fprintf(fh, "\t(hap %s)\n", libxl_defbool_to_string(c_info->hap));
+    fprintf(fh, "\t(oos %s)\n", libxl_defbool_to_string(c_info->oos));
+    fprintf(fh, "\t(ssidref %d)\n", c_info->ssidref);
+    fprintf(fh, "\t(name %s)\n", c_info->name);
 
     /* retrieve the UUID from dominfo, since it is probably generated
      * during parsing and thus does not match the real one
      */
     if (libxl_domain_info(ctx, &info, domid) == 0) {
-        printf("\t(uuid " LIBXL_UUID_FMT ")\n", LIBXL_UUID_BYTES(info.uuid));
+        fprintf(fh, "\t(uuid " LIBXL_UUID_FMT ")\n", LIBXL_UUID_BYTES(info.uuid));
     } else {
-        printf("\t(uuid <unknown>)\n");
+        fprintf(fh, "\t(uuid <unknown>)\n");
     }
     if (c_info->pool_name)
-        printf("\t(cpupool %s)\n", c_info->pool_name);
+        fprintf(fh, "\t(cpupool %s)\n", c_info->pool_name);
     if (c_info->xsdata)
-        printf("\t(xsdata contains data)\n");
+        fprintf(fh, "\t(xsdata contains data)\n");
     else
-        printf("\t(xsdata (null))\n");
+        fprintf(fh, "\t(xsdata (null))\n");
     if (c_info->platformdata)
-        printf("\t(platformdata contains data)\n");
+        fprintf(fh, "\t(platformdata contains data)\n");
     else
-        printf("\t(platformdata (null))\n");
+        fprintf(fh, "\t(platformdata (null))\n");
 
 
-    printf("\t(build_info)\n");
-    printf("\t(max_vcpus %d)\n", b_info->max_vcpus);
-    printf("\t(tsc_mode %s)\n", libxl_tsc_mode_to_string(b_info->tsc_mode));
-    printf("\t(max_memkb %"PRId64")\n", b_info->max_memkb);
-    printf("\t(target_memkb %"PRId64")\n", b_info->target_memkb);
-    printf("\t(nomigrate %s)\n",
+    fprintf(fh, "\t(build_info)\n");
+    fprintf(fh, "\t(max_vcpus %d)\n", b_info->max_vcpus);
+    fprintf(fh, "\t(tsc_mode %s)\n", libxl_tsc_mode_to_string(b_info->tsc_mode));
+    fprintf(fh, "\t(max_memkb %"PRId64")\n", b_info->max_memkb);
+    fprintf(fh, "\t(target_memkb %"PRId64")\n", b_info->target_memkb);
+    fprintf(fh, "\t(nomigrate %s)\n",
            libxl_defbool_to_string(b_info->disable_migrate));
 
     if (c_info->type == LIBXL_DOMAIN_TYPE_PV && b_info->u.pv.bootloader) {
-        printf("\t(bootloader %s)\n", b_info->u.pv.bootloader);
+        fprintf(fh, "\t(bootloader %s)\n", b_info->u.pv.bootloader);
         if (b_info->u.pv.bootloader_args) {
-            printf("\t(bootloader_args");
+            fprintf(fh, "\t(bootloader_args");
             for (i=0; b_info->u.pv.bootloader_args[i]; i++)
-                printf(" %s", b_info->u.pv.bootloader_args[i]);
-            printf(")\n");
+                fprintf(fh, " %s", b_info->u.pv.bootloader_args[i]);
+            fprintf(fh, ")\n");
         }
     }
 
-    printf("\t(image\n");
+    fprintf(fh, "\t(image\n");
     switch (c_info->type) {
     case LIBXL_DOMAIN_TYPE_HVM:
-        printf("\t\t(hvm\n");
-        printf("\t\t\t(firmware %s)\n", b_info->u.hvm.firmware);
-        printf("\t\t\t(video_memkb %"PRId64")\n", b_info->video_memkb);
-        printf("\t\t\t(shadow_memkb %"PRId64")\n", b_info->shadow_memkb);
-        printf("\t\t\t(pae %s)\n", libxl_defbool_to_string(b_info->u.hvm.pae));
-        printf("\t\t\t(apic %s)\n",
+        fprintf(fh, "\t\t(hvm\n");
+        fprintf(fh, "\t\t\t(firmware %s)\n", b_info->u.hvm.firmware);
+        fprintf(fh, "\t\t\t(video_memkb %"PRId64")\n", b_info->video_memkb);
+        fprintf(fh, "\t\t\t(shadow_memkb %"PRId64")\n", b_info->shadow_memkb);
+        fprintf(fh, "\t\t\t(pae %s)\n", libxl_defbool_to_string(b_info->u.hvm.pae));
+        fprintf(fh, "\t\t\t(apic %s)\n",
                libxl_defbool_to_string(b_info->u.hvm.apic));
-        printf("\t\t\t(acpi %s)\n",
+        fprintf(fh, "\t\t\t(acpi %s)\n",
                libxl_defbool_to_string(b_info->u.hvm.acpi));
-        printf("\t\t\t(nx %s)\n", libxl_defbool_to_string(b_info->u.hvm.nx));
-        printf("\t\t\t(viridian %s)\n",
+        fprintf(fh, "\t\t\t(nx %s)\n", libxl_defbool_to_string(b_info->u.hvm.nx));
+        fprintf(fh, "\t\t\t(viridian %s)\n",
                libxl_defbool_to_string(b_info->u.hvm.viridian));
-        printf("\t\t\t(hpet %s)\n",
+        fprintf(fh, "\t\t\t(hpet %s)\n",
                libxl_defbool_to_string(b_info->u.hvm.hpet));
-        printf("\t\t\t(vpt_align %s)\n",
+        fprintf(fh, "\t\t\t(vpt_align %s)\n",
                libxl_defbool_to_string(b_info->u.hvm.vpt_align));
-        printf("\t\t\t(timer_mode %s)\n",
+        fprintf(fh, "\t\t\t(timer_mode %s)\n",
                libxl_timer_mode_to_string(b_info->u.hvm.timer_mode));
-        printf("\t\t\t(nestedhvm %s)\n",
+        fprintf(fh, "\t\t\t(nestedhvm %s)\n",
                libxl_defbool_to_string(b_info->u.hvm.nested_hvm));
-        printf("\t\t\t(stdvga %s)\n", b_info->u.hvm.vga.kind ==
+        fprintf(fh, "\t\t\t(stdvga %s)\n", b_info->u.hvm.vga.kind ==
                                       LIBXL_VGA_INTERFACE_TYPE_STD ?
                                       "True" : "False");
-        printf("\t\t\t(vnc %s)\n",
+        fprintf(fh, "\t\t\t(vnc %s)\n",
                libxl_defbool_to_string(b_info->u.hvm.vnc.enable));
-        printf("\t\t\t(vnclisten %s)\n", b_info->u.hvm.vnc.listen);
-        printf("\t\t\t(vncdisplay %d)\n", b_info->u.hvm.vnc.display);
-        printf("\t\t\t(vncunused %s)\n",
+        fprintf(fh, "\t\t\t(vnclisten %s)\n", b_info->u.hvm.vnc.listen);
+        fprintf(fh, "\t\t\t(vncdisplay %d)\n", b_info->u.hvm.vnc.display);
+        fprintf(fh, "\t\t\t(vncunused %s)\n",
                libxl_defbool_to_string(b_info->u.hvm.vnc.findunused));
-        printf("\t\t\t(keymap %s)\n", b_info->u.hvm.keymap);
-        printf("\t\t\t(sdl %s)\n",
+        fprintf(fh, "\t\t\t(keymap %s)\n", b_info->u.hvm.keymap);
+        fprintf(fh, "\t\t\t(sdl %s)\n",
                libxl_defbool_to_string(b_info->u.hvm.sdl.enable));
-        printf("\t\t\t(opengl %s)\n",
+        fprintf(fh, "\t\t\t(opengl %s)\n",
                libxl_defbool_to_string(b_info->u.hvm.sdl.opengl));
-        printf("\t\t\t(nographic %s)\n",
+        fprintf(fh, "\t\t\t(nographic %s)\n",
                libxl_defbool_to_string(b_info->u.hvm.nographic));
-        printf("\t\t\t(spice %s)\n",
+        fprintf(fh, "\t\t\t(spice %s)\n",
                libxl_defbool_to_string(b_info->u.hvm.spice.enable));
-        printf("\t\t\t(spiceport %d)\n", b_info->u.hvm.spice.port);
-        printf("\t\t\t(spicetls_port %d)\n", b_info->u.hvm.spice.tls_port);
-        printf("\t\t\t(spicehost %s)\n", b_info->u.hvm.spice.host);
-        printf("\t\t\t(spicedisable_ticketing %s)\n",
+        fprintf(fh, "\t\t\t(spiceport %d)\n", b_info->u.hvm.spice.port);
+        fprintf(fh, "\t\t\t(spicetls_port %d)\n", b_info->u.hvm.spice.tls_port);
+        fprintf(fh, "\t\t\t(spicehost %s)\n", b_info->u.hvm.spice.host);
+        fprintf(fh, "\t\t\t(spicedisable_ticketing %s)\n",
                libxl_defbool_to_string(b_info->u.hvm.spice.disable_ticketing));
-        printf("\t\t\t(spiceagent_mouse %s)\n",
+        fprintf(fh, "\t\t\t(spiceagent_mouse %s)\n",
                libxl_defbool_to_string(b_info->u.hvm.spice.agent_mouse));
 
-        printf("\t\t\t(device_model %s)\n", b_info->device_model ? : "default");
-        printf("\t\t\t(gfx_passthru %s)\n",
+        fprintf(fh, "\t\t\t(device_model %s)\n", b_info->device_model ? : "default");
+        fprintf(fh, "\t\t\t(gfx_passthru %s)\n",
                libxl_defbool_to_string(b_info->u.hvm.gfx_passthru));
-        printf("\t\t\t(serial %s)\n", b_info->u.hvm.serial);
-        printf("\t\t\t(boot %s)\n", b_info->u.hvm.boot);
-        printf("\t\t\t(usb %s)\n", libxl_defbool_to_string(b_info->u.hvm.usb));
-        printf("\t\t\t(usbdevice %s)\n", b_info->u.hvm.usbdevice);
-        printf("\t\t)\n");
+        fprintf(fh, "\t\t\t(serial %s)\n", b_info->u.hvm.serial);
+        fprintf(fh, "\t\t\t(boot %s)\n", b_info->u.hvm.boot);
+        fprintf(fh, "\t\t\t(usb %s)\n", libxl_defbool_to_string(b_info->u.hvm.usb));
+        fprintf(fh, "\t\t\t(usbdevice %s)\n", b_info->u.hvm.usbdevice);
+        fprintf(fh, "\t\t)\n");
         break;
     case LIBXL_DOMAIN_TYPE_PV:
-        printf("\t\t(linux %d)\n", 0);
-        printf("\t\t\t(kernel %s)\n", b_info->kernel);
-        printf("\t\t\t(cmdline %s)\n", b_info->cmdline);
-        printf("\t\t\t(ramdisk %s)\n", b_info->ramdisk);
-        printf("\t\t\t(e820_host %s)\n",
+        fprintf(fh, "\t\t(linux %d)\n", 0);
+        fprintf(fh, "\t\t\t(kernel %s)\n", b_info->kernel);
+        fprintf(fh, "\t\t\t(cmdline %s)\n", b_info->cmdline);
+        fprintf(fh, "\t\t\t(ramdisk %s)\n", b_info->ramdisk);
+        fprintf(fh, "\t\t\t(e820_host %s)\n",
                libxl_defbool_to_string(b_info->u.pv.e820_host));
-        printf("\t\t)\n");
+        fprintf(fh, "\t\t)\n");
         break;
     default:
         fprintf(stderr, "Unknown domain type %d\n", c_info->type);
         exit(1);
     }
-    printf("\t)\n");
+    fprintf(fh, "\t)\n");
 
     for (i = 0; i < d_config->num_disks; i++) {
-        printf("\t(device\n");
-        printf("\t\t(tap\n");
-        printf("\t\t\t(backend_domid %d)\n", d_config->disks[i].backend_domid);
-        printf("\t\t\t(frontend_domid %d)\n", domid);
-        printf("\t\t\t(physpath %s)\n", d_config->disks[i].pdev_path);
-        printf("\t\t\t(phystype %d)\n", d_config->disks[i].backend);
-        printf("\t\t\t(virtpath %s)\n", d_config->disks[i].vdev);
-        printf("\t\t\t(unpluggable %d)\n", d_config->disks[i].removable);
-        printf("\t\t\t(readwrite %d)\n", d_config->disks[i].readwrite);
-        printf("\t\t\t(is_cdrom %d)\n", d_config->disks[i].is_cdrom);
-        printf("\t\t)\n");
-        printf("\t)\n");
+        fprintf(fh, "\t(device\n");
+        fprintf(fh, "\t\t(tap\n");
+        fprintf(fh, "\t\t\t(backend_domid %d)\n", d_config->disks[i].backend_domid);
+        fprintf(fh, "\t\t\t(frontend_domid %d)\n", domid);
+        fprintf(fh, "\t\t\t(physpath %s)\n", d_config->disks[i].pdev_path);
+        fprintf(fh, "\t\t\t(phystype %d)\n", d_config->disks[i].backend);
+        fprintf(fh, "\t\t\t(virtpath %s)\n", d_config->disks[i].vdev);
+        fprintf(fh, "\t\t\t(unpluggable %d)\n", d_config->disks[i].removable);
+        fprintf(fh, "\t\t\t(readwrite %d)\n", d_config->disks[i].readwrite);
+        fprintf(fh, "\t\t\t(is_cdrom %d)\n", d_config->disks[i].is_cdrom);
+        fprintf(fh, "\t\t)\n");
+        fprintf(fh, "\t)\n");
     }
 
     for (i = 0; i < d_config->num_nics; i++) {
-        printf("\t(device\n");
-        printf("\t\t(vif\n");
+        fprintf(fh, "\t(device\n");
+        fprintf(fh, "\t\t(vif\n");
         if (d_config->nics[i].ifname)
-            printf("\t\t\t(vifname %s)\n", d_config->nics[i].ifname);
-        printf("\t\t\t(backend_domid %d)\n", d_config->nics[i].backend_domid);
-        printf("\t\t\t(frontend_domid %d)\n", domid);
-        printf("\t\t\t(devid %d)\n", d_config->nics[i].devid);
-        printf("\t\t\t(mtu %d)\n", d_config->nics[i].mtu);
-        printf("\t\t\t(model %s)\n", d_config->nics[i].model);
-        printf("\t\t\t(mac %02x%02x%02x%02x%02x%02x)\n",
+            fprintf(fh, "\t\t\t(vifname %s)\n", d_config->nics[i].ifname);
+        fprintf(fh, "\t\t\t(backend_domid %d)\n", d_config->nics[i].backend_domid);
+        fprintf(fh, "\t\t\t(frontend_domid %d)\n", domid);
+        fprintf(fh, "\t\t\t(devid %d)\n", d_config->nics[i].devid);
+        fprintf(fh, "\t\t\t(mtu %d)\n", d_config->nics[i].mtu);
+        fprintf(fh, "\t\t\t(model %s)\n", d_config->nics[i].model);
+        fprintf(fh, "\t\t\t(mac %02x%02x%02x%02x%02x%02x)\n",
                d_config->nics[i].mac[0], d_config->nics[i].mac[1],
                d_config->nics[i].mac[2], d_config->nics[i].mac[3],
                d_config->nics[i].mac[4], d_config->nics[i].mac[5]);
-        printf("\t\t)\n");
-        printf("\t)\n");
+        fprintf(fh, "\t\t)\n");
+        fprintf(fh, "\t)\n");
     }
 
     for (i = 0; i < d_config->num_pcidevs; i++) {
-        printf("\t(device\n");
-        printf("\t\t(pci\n");
-        printf("\t\t\t(pci dev %04x:%02x:%02x.%01x@%02x)\n",
+        fprintf(fh, "\t(device\n");
+        fprintf(fh, "\t\t(pci\n");
+        fprintf(fh, "\t\t\t(pci dev %04x:%02x:%02x.%01x@%02x)\n",
                d_config->pcidevs[i].domain, d_config->pcidevs[i].bus,
                d_config->pcidevs[i].dev, d_config->pcidevs[i].func,
                d_config->pcidevs[i].vdevfn);
-        printf("\t\t\t(opts msitranslate %d power_mgmt %d)\n",
+        fprintf(fh, "\t\t\t(opts msitranslate %d power_mgmt %d)\n",
                d_config->pcidevs[i].msitranslate,
                d_config->pcidevs[i].power_mgmt);
-        printf("\t\t)\n");
-        printf("\t)\n");
+        fprintf(fh, "\t\t)\n");
+        fprintf(fh, "\t)\n");
     }
 
     for (i = 0; i < d_config->num_vfbs; i++) {
-        printf("\t(device\n");
-        printf("\t\t(vfb\n");
-        printf("\t\t\t(backend_domid %d)\n", d_config->vfbs[i].backend_domid);
-        printf("\t\t\t(frontend_domid %d)\n", domid);
-        printf("\t\t\t(devid %d)\n", d_config->vfbs[i].devid);
-        printf("\t\t\t(vnc %s)\n",
+        fprintf(fh, "\t(device\n");
+        fprintf(fh, "\t\t(vfb\n");
+        fprintf(fh, "\t\t\t(backend_domid %d)\n", d_config->vfbs[i].backend_domid);
+        fprintf(fh, "\t\t\t(frontend_domid %d)\n", domid);
+        fprintf(fh, "\t\t\t(devid %d)\n", d_config->vfbs[i].devid);
+        fprintf(fh, "\t\t\t(vnc %s)\n",
                libxl_defbool_to_string(d_config->vfbs[i].vnc.enable));
-        printf("\t\t\t(vnclisten %s)\n", d_config->vfbs[i].vnc.listen);
-        printf("\t\t\t(vncdisplay %d)\n", d_config->vfbs[i].vnc.display);
-        printf("\t\t\t(vncunused %s)\n",
+        fprintf(fh, "\t\t\t(vnclisten %s)\n", d_config->vfbs[i].vnc.listen);
+        fprintf(fh, "\t\t\t(vncdisplay %d)\n", d_config->vfbs[i].vnc.display);
+        fprintf(fh, "\t\t\t(vncunused %s)\n",
                libxl_defbool_to_string(d_config->vfbs[i].vnc.findunused));
-        printf("\t\t\t(keymap %s)\n", d_config->vfbs[i].keymap);
-        printf("\t\t\t(sdl %s)\n",
+        fprintf(fh, "\t\t\t(keymap %s)\n", d_config->vfbs[i].keymap);
+        fprintf(fh, "\t\t\t(sdl %s)\n",
                libxl_defbool_to_string(d_config->vfbs[i].sdl.enable));
-        printf("\t\t\t(opengl %s)\n",
+        fprintf(fh, "\t\t\t(opengl %s)\n",
                libxl_defbool_to_string(d_config->vfbs[i].sdl.opengl));
-        printf("\t\t\t(display %s)\n", d_config->vfbs[i].sdl.display);
-        printf("\t\t\t(xauthority %s)\n", d_config->vfbs[i].sdl.xauthority);
-        printf("\t\t)\n");
-        printf("\t)\n");
+        fprintf(fh, "\t\t\t(display %s)\n", d_config->vfbs[i].sdl.display);
+        fprintf(fh, "\t\t\t(xauthority %s)\n", d_config->vfbs[i].sdl.xauthority);
+        fprintf(fh, "\t\t)\n");
+        fprintf(fh, "\t)\n");
     }
-    printf(")\n");
+    fprintf(fh, ")\n");
 }
 
 
diff --git a/tools/pygrub/src/pygrub b/tools/pygrub/src/pygrub
old mode 100644
new mode 100755
index aa7e562..3ec52fd
--- a/tools/pygrub/src/pygrub
+++ b/tools/pygrub/src/pygrub
@@ -457,7 +457,9 @@ class Grub:
         self.cf.parse(buf)
 
     def image_index(self):
-        if self.cf.default.isdigit():
+        if isinstance(self.cf.default, int):
+            sel = self.cf.default
+        elif self.cf.default.isdigit():
             sel = int(self.cf.default)
         else:
             # We don't fully support submenus. Look for the leaf value in
diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c
index d95d459..2aa0dc7 100644
--- a/tools/python/xen/lowlevel/xc/xc.c
+++ b/tools/python/xen/lowlevel/xc/xc.c
@@ -1089,7 +1089,7 @@ static PyObject *pyxc_readconsolering(XcObject *self,
 {
     unsigned int clear = 0, index = 0, incremental = 0;
     unsigned int count = 16384 + 1, size = count;
-    char        *str = malloc(size), *ptr;
+    char        *str, *ptr;
     PyObject    *obj;
     int          ret;
 
@@ -1097,15 +1097,17 @@ static PyObject *pyxc_readconsolering(XcObject *self,
 
     if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iii", kwd_list,
                                       &clear, &index, &incremental) ||
-         !str )
+         !(str = malloc(size)) )
         return NULL;
 
     ret = xc_readconsolering(self->xc_handle, str, &count, clear,
                              incremental, &index);
-    if ( ret < 0 )
+    if ( ret < 0 ) {
+        free(str);
         return pyxc_error_to_exception(self->xc_handle);
+    }
 
-    while ( !incremental && count == size )
+    while ( !incremental && count == size && ret >= 0 )
     {
         size += count - 1;
         if ( size < count )
@@ -1119,9 +1121,6 @@ static PyObject *pyxc_readconsolering(XcObject *self,
         count = size - count;
         ret = xc_readconsolering(self->xc_handle, str, &count, clear,
                                  1, &index);
-        if ( ret < 0 )
-            break;
-
         count += str - ptr;
         str = ptr;
     }
@@ -2126,8 +2125,6 @@ static PyObject *pyflask_context_to_sid(PyObject *self, PyObject *args,
 {
     xc_interface *xc_handle;
     char *ctx;
-    char *buf;
-    uint32_t len;
     uint32_t sid;
     int ret;
 
@@ -2137,28 +2134,15 @@ static PyObject *pyflask_context_to_sid(PyObject *self, PyObject *args,
                                       &ctx) )
         return NULL;
 
-    len = strlen(ctx);
-
-    buf = malloc(len);
-    if (!buf) {
-        errno = -ENOMEM;
-        PyErr_SetFromErrno(xc_error_obj);
-    }
-    
-    memcpy(buf, ctx, len);
-    
     xc_handle = xc_interface_open(0,0,0);
     if (!xc_handle) {
-        free(buf);
         return PyErr_SetFromErrno(xc_error_obj);
     }
-    
-    ret = xc_flask_context_to_sid(xc_handle, buf, len, &sid);
-        
+
+    ret = xc_flask_context_to_sid(xc_handle, ctx, strlen(ctx), &sid);
+
     xc_interface_close(xc_handle);
 
-    free(buf);
-    
     if ( ret != 0 ) {
         errno = -ret;
         return PyErr_SetFromErrno(xc_error_obj);
diff --git a/tools/python/xen/lowlevel/xs/xs.c b/tools/python/xen/lowlevel/xs/xs.c
index 84e1711..ec364bb 100644
--- a/tools/python/xen/lowlevel/xs/xs.c
+++ b/tools/python/xen/lowlevel/xs/xs.c
@@ -816,7 +816,7 @@ static int parse_transaction_path(XsHandle *self, PyObject *args,
 
     *xh = xshandle(self);
 
-    if (!xh)
+    if (!*xh)
         return 0;
 
     if (!PyArg_ParseTuple(args, "ss", &thstr, path))
diff --git a/tools/xenstore/Makefile b/tools/xenstore/Makefile
index bff9b25..11b6a06 100644
--- a/tools/xenstore/Makefile
+++ b/tools/xenstore/Makefile
@@ -74,10 +74,10 @@ endif
 init-xenstore-domain.o: CFLAGS += $(CFLAGS_libxenguest)
 
 init-xenstore-domain: init-xenstore-domain.o $(LIBXENSTORE)
-	$(CC) $(LDFLAGS) $^ $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) -o $@ $(APPEND_LDFLAGS)
+	$(CC) $^ $(LDFLAGS) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) -o $@ $(APPEND_LDFLAGS)
 
 xenstored: $(XENSTORED_OBJS)
-	$(CC) $(LDFLAGS) $^ $(LDLIBS_libxenctrl) $(SOCKET_LIBS) -o $@ $(APPEND_LDFLAGS)
+	$(CC) $^ $(LDFLAGS) $(LDLIBS_libxenctrl) $(SOCKET_LIBS) -o $@ $(APPEND_LDFLAGS)
 
 xenstored.a: $(XENSTORED_OBJS)
 	$(AR) cr $@ $^
@@ -86,13 +86,13 @@ $(CLIENTS): xenstore
 	ln -f xenstore $@
 
 xenstore: xenstore_client.o $(LIBXENSTORE)
-	$(CC) $(LDFLAGS) $< $(LDLIBS_libxenstore) $(SOCKET_LIBS) -o $@ $(APPEND_LDFLAGS)
+	$(CC) $< $(LDFLAGS) $(LDLIBS_libxenstore) $(SOCKET_LIBS) -o $@ $(APPEND_LDFLAGS)
 
 xenstore-control: xenstore_control.o $(LIBXENSTORE)
-	$(CC) $(LDFLAGS) $< $(LDLIBS_libxenstore) $(SOCKET_LIBS) -o $@ $(APPEND_LDFLAGS)
+	$(CC) $< $(LDFLAGS) $(LDLIBS_libxenstore) $(SOCKET_LIBS) -o $@ $(APPEND_LDFLAGS)
 
 xs_tdb_dump: xs_tdb_dump.o utils.o tdb.o talloc.o
-	$(CC) $(LDFLAGS) $^ -o $@ $(APPEND_LDFLAGS)
+	$(CC) $^ $(LDFLAGS) -o $@ $(APPEND_LDFLAGS)
 
 libxenstore.so: libxenstore.so.$(MAJOR)
 	ln -sf $< $@
diff --git a/tools/xenstore/include/xenstore.h b/tools/xenstore/include/xenstore.h
index fdf5e76..b4b113e 100644
--- a/tools/xenstore/include/xenstore.h
+++ b/tools/xenstore/include/xenstore.h
@@ -59,10 +59,20 @@ typedef uint32_t xs_transaction_t;
 /* On failure, these routines set errno. */
 
 /* Open a connection to the xs daemon.
- * Attempts to make a connection over the socket interface, 
+ * Attempts to make a connection over the socket interface,
  * and if it fails, then over the  xenbus interface.
  * Mode 0 specifies read-write access, XS_OPEN_READONLY for
  * read-only access.
+ *
+ * * Connections made with xs_open(0) (which might be shared page or
+ *   socket based) are only guaranteed to work in the parent after
+ *   fork.
+ * * Connections made with xs_open(XS_OPEN_SOCKETONLY) will be usable
+ *   in either the parent or the child after fork, but not both.
+ * * xs_daemon_open*() and xs_domain_open() are deprecated synonyms
+ *   for xs_open(0).
+ * * XS_OPEN_READONLY has no bearing on any of this.
+ *
  * Returns a handle or NULL.
  */
 struct xs_handle *xs_open(unsigned long flags);
diff --git a/xen/Makefile b/xen/Makefile
index 72c1313..5d70741 100644
--- a/xen/Makefile
+++ b/xen/Makefile
@@ -2,7 +2,7 @@
 # All other places this is stored (eg. compile.h) should be autogenerated.
 export XEN_VERSION       = 4
 export XEN_SUBVERSION    = 5
-export XEN_EXTRAVERSION ?= .0-rc$(XEN_VENDORVERSION)
+export XEN_EXTRAVERSION ?= .0$(XEN_VENDORVERSION)
 export XEN_FULLVERSION   = $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION)
 -include xen-version
 
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index d2dcc3a..f49569d 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -286,7 +286,7 @@ static paddr_t __init consider_modules(paddr_t s, paddr_t e,
         return 0;
 
     /* First check the boot modules */
-    for ( i = first_mod; i <= mi->nr_mods; i++ )
+    for ( i = first_mod; i < mi->nr_mods; i++ )
     {
         paddr_t mod_s = mi->module[i].start;
         paddr_t mod_e = mod_s + mi->module[i].size;
@@ -745,6 +745,7 @@ void __init start_xen(unsigned long boot_phys_offset,
 
     dt_uart_init();
     console_init_preirq();
+    console_init_ring();
 
     system_state = SYS_STATE_boot;
 
diff --git a/xen/arch/arm/time.c b/xen/arch/arm/time.c
index a6436f1..0add494 100644
--- a/xen/arch/arm/time.c
+++ b/xen/arch/arm/time.c
@@ -169,6 +169,19 @@ static void timer_interrupt(int irq, void *dev_id, struct cpu_user_regs *regs)
 
 static void vtimer_interrupt(int irq, void *dev_id, struct cpu_user_regs *regs)
 {
+    /*
+     * Edge-triggered interrupts can be used for the virtual timer. Even
+     * if the timer output signal is masked in the context switch, the
+     * GIC will keep track that of any interrupts raised while IRQS are
+     * disabled. As soon as IRQs are re-enabled, the virtual interrupt
+     * will be injected to Xen.
+     *
+     * If an IDLE vCPU was scheduled next then we should ignore the
+     * interrupt.
+     */
+    if ( unlikely(is_idle_vcpu(current)) )
+        return;
+
     current->arch.virt_timer.ctl = READ_SYSREG32(CNTV_CTL_EL0);
     WRITE_SYSREG32(current->arch.virt_timer.ctl | CNTx_CTL_MASK, CNTV_CTL_EL0);
     vgic_vcpu_inject_irq(current, current->arch.virt_timer.irq);
diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index 97061ce..b8bd38b 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -90,6 +90,8 @@ int domain_vgic_init(struct domain *d)
         return -ENODEV;
     }
 
+    spin_lock_init(&d->arch.vgic.lock);
+
     d->arch.vgic.shared_irqs =
         xzalloc_array(struct vgic_irq_rank, DOMAIN_NR_RANKS(d));
     if ( d->arch.vgic.shared_irqs == NULL )
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 11c7d9f..f1fc993 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -1969,9 +1969,7 @@ int domain_relinquish_resources(struct domain *d)
     switch ( d->arch.relmem )
     {
     case RELMEM_not_started:
-        ret = pci_release_devices(d);
-        if ( ret )
-            return ret;
+        pci_release_devices(d);
 
         /* Tear down paging-assistance stuff. */
         ret = paging_teardown(d);
diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c
index 7a6afea..7993b17 100644
--- a/xen/arch/x86/domain_build.c
+++ b/xen/arch/x86/domain_build.c
@@ -101,7 +101,7 @@ static void __init parse_dom0_max_vcpus(const char *s)
 }
 custom_param("dom0_max_vcpus", parse_dom0_max_vcpus);
 
-struct vcpu *__init alloc_dom0_vcpu0(struct domain *dom0)
+unsigned int __init dom0_max_vcpus(void)
 {
     unsigned max_vcpus;
 
@@ -113,6 +113,13 @@ struct vcpu *__init alloc_dom0_vcpu0(struct domain *dom0)
     if ( max_vcpus > MAX_VIRT_CPUS )
         max_vcpus = MAX_VIRT_CPUS;
 
+    return max_vcpus;
+}
+
+struct vcpu *__init alloc_dom0_vcpu0(struct domain *dom0)
+{
+    unsigned int max_vcpus = dom0_max_vcpus();
+
     dom0->vcpu = xzalloc_array(struct vcpu *, max_vcpus);
     if ( !dom0->vcpu )
         return NULL;
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 51ffc90..72be5b9 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -1487,9 +1487,6 @@ int hvm_domain_initialise(struct domain *d)
 
 void hvm_domain_relinquish_resources(struct domain *d)
 {
-    xfree(d->arch.hvm_domain.io_handler);
-    xfree(d->arch.hvm_domain.params);
-
     if ( is_pvh_domain(d) )
         return;
 
@@ -1511,6 +1508,9 @@ void hvm_domain_relinquish_resources(struct domain *d)
 
 void hvm_domain_destroy(struct domain *d)
 {
+    xfree(d->arch.hvm_domain.io_handler);
+    xfree(d->arch.hvm_domain.params);
+
     hvm_destroy_cacheattr_region_list(d);
 
     if ( is_pvh_domain(d) )
@@ -5458,16 +5458,34 @@ static int hvmop_destroy_ioreq_server(
     return rc;
 }
 
+/*
+ * Note that this value is effectively part of the ABI, even if we don't need
+ * to make it a formal part of it: A guest suspended for migration in the
+ * middle of a continuation would fail to work if resumed on a hypervisor
+ * using a different value.
+ */
 #define HVMOP_op_mask 0xff
 
 long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg)
 
 {
     struct domain *curr_d = current->domain;
-    unsigned long start_iter = op & ~HVMOP_op_mask;
+    unsigned long start_iter, mask;
     long rc = 0;
 
-    switch ( op &= HVMOP_op_mask )
+    switch ( op & HVMOP_op_mask )
+    {
+    default:
+        mask = ~0UL;
+        break;
+    case HVMOP_modified_memory:
+    case HVMOP_set_mem_type:
+        mask = HVMOP_op_mask;
+        break;
+    }
+
+    start_iter = op & ~mask;
+    switch ( op &= mask )
     {
     case HVMOP_create_ioreq_server:
         rc = hvmop_create_ioreq_server(
@@ -6120,7 +6138,7 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg)
 
     if ( rc == -ERESTART )
     {
-        ASSERT(!(start_iter & HVMOP_op_mask));
+        ASSERT(!(start_iter & mask));
         rc = hypercall_create_continuation(__HYPERVISOR_hvm_op, "lh",
                                            op | start_iter, arg);
     }
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 9398690..a7655bd 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -2371,8 +2371,8 @@ void svm_vmexit_handler(struct cpu_user_regs *regs)
                 goto out;
             case NESTEDHVM_VMEXIT_FATALERROR:
                 gdprintk(XENLOG_ERR, "unexpected nestedsvm_vmexit() error\n");
-                goto exit_and_crash;
-
+                domain_crash(v->domain);
+                goto out;
             default:
                 BUG();
             case NESTEDHVM_VMEXIT_ERROR:
@@ -2385,18 +2385,22 @@ void svm_vmexit_handler(struct cpu_user_regs *regs)
         case NESTEDHVM_VMEXIT_FATALERROR:
             gdprintk(XENLOG_ERR,
                 "unexpected nestedsvm_check_intercepts() error\n");
-            goto exit_and_crash;
+            domain_crash(v->domain);
+            goto out;
         default:
             gdprintk(XENLOG_INFO, "nestedsvm_check_intercepts() returned %i\n",
                 nsret);
-            goto exit_and_crash;
+            domain_crash(v->domain);
+            goto out;
         }
     }
 
     if ( unlikely(exit_reason == VMEXIT_INVALID) )
     {
+        gdprintk(XENLOG_ERR, "invalid VMCB state:\n");
         svm_vmcb_dump(__func__, vmcb);
-        goto exit_and_crash;
+        domain_crash(v->domain);
+        goto out;
     }
 
     perfc_incra(svmexits, exit_reason);
@@ -2431,13 +2435,13 @@ void svm_vmexit_handler(struct cpu_user_regs *regs)
 
     case VMEXIT_EXCEPTION_DB:
         if ( !v->domain->debugger_attached )
-            goto exit_and_crash;
+            goto unexpected_exit_type;
         domain_pause_for_debugger();
         break;
 
     case VMEXIT_EXCEPTION_BP:
         if ( !v->domain->debugger_attached )
-            goto exit_and_crash;
+            goto unexpected_exit_type;
         /* AMD Vol2, 15.11: INT3, INTO, BOUND intercepts do not update RIP. */
         if ( (inst_len = __get_instruction_length(v, INSTR_INT3)) == 0 )
             break;
@@ -2684,7 +2688,7 @@ void svm_vmexit_handler(struct cpu_user_regs *regs)
         break;
 
     default:
-    exit_and_crash:
+    unexpected_exit_type:
         gdprintk(XENLOG_ERR, "unexpected VMEXIT: exit reason = %#"PRIx64", "
                  "exitinfo1 = %#"PRIx64", exitinfo2 = %#"PRIx64"\n",
                  exit_reason, 
diff --git a/xen/arch/x86/hvm/svm/vpmu.c b/xen/arch/x86/hvm/svm/vpmu.c
index 8e07a98..4c448bb 100644
--- a/xen/arch/x86/hvm/svm/vpmu.c
+++ b/xen/arch/x86/hvm/svm/vpmu.c
@@ -403,9 +403,6 @@ static void amd_vpmu_destroy(struct vcpu *v)
 {
     struct vpmu_struct *vpmu = vcpu_vpmu(v);
 
-    if ( !vpmu_is_set(vpmu, VPMU_CONTEXT_ALLOCATED) )
-        return;
-
     if ( ((struct amd_vpmu_context *)vpmu->context)->msr_bitmap_set )
         amd_vpmu_unset_msr_bitmap(v);
 
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index 2907afa..f2554d6 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -134,18 +134,6 @@ static void vmx_vcpu_destroy(struct vcpu *v)
     passive_domain_destroy(v);
 }
 
-/* Only crash the guest if the problem originates in kernel mode. */
-static void vmx_crash_or_fault(struct vcpu *v)
-{
-    struct segment_register ss;
-
-    vmx_get_segment_register(v, x86_seg_ss, &ss);
-    if ( ss.attr.fields.dpl )
-        hvm_inject_hw_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE);
-    else
-        domain_crash(v->domain);
-}
-
 static DEFINE_PER_CPU(struct vmx_msr_state, host_msr_state);
 
 static const u32 msr_index[] =
@@ -2520,7 +2508,7 @@ static void vmx_failed_vmentry(unsigned int exit_reason,
     vmcs_dump_vcpu(curr);
     printk("**************************************\n");
 
-    vmx_crash_or_fault(curr);
+    domain_crash(curr->domain);
 }
 
 void vmx_enter_realmode(struct cpu_user_regs *regs)
@@ -3098,7 +3086,8 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
         if ( exit_qualification & 0x10 )
         {
             /* INS, OUTS */
-            if ( !handle_mmio() )
+            if ( unlikely(is_pvh_vcpu(v)) /* PVH fixme */ ||
+                 !handle_mmio() )
                 hvm_inject_hw_exception(TRAP_gp_fault, 0);
         }
         else
@@ -3173,8 +3162,19 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
     /* fall through */
     default:
     exit_and_crash:
-        gdprintk(XENLOG_WARNING, "Bad vmexit (reason %#lx)\n", exit_reason);
-        vmx_crash_or_fault(v);
+        {
+            struct segment_register ss;
+
+            gdprintk(XENLOG_WARNING, "Bad vmexit (reason %#lx)\n",
+                     exit_reason);
+
+            vmx_get_segment_register(v, x86_seg_ss, &ss);
+            if ( ss.attr.fields.dpl )
+                hvm_inject_hw_exception(TRAP_invalid_op,
+                                        HVM_DELIVER_NO_ERROR_CODE);
+            else
+                domain_crash(v->domain);
+        }
         break;
     }
 
diff --git a/xen/arch/x86/hvm/vmx/vpmu_core2.c b/xen/arch/x86/hvm/vmx/vpmu_core2.c
index 68b6272..590c2a9 100644
--- a/xen/arch/x86/hvm/vmx/vpmu_core2.c
+++ b/xen/arch/x86/hvm/vmx/vpmu_core2.c
@@ -818,8 +818,6 @@ static void core2_vpmu_destroy(struct vcpu *v)
     struct vpmu_struct *vpmu = vcpu_vpmu(v);
     struct core2_vpmu_context *core2_vpmu_cxt = vpmu->context;
 
-    if ( !vpmu_is_set(vpmu, VPMU_CONTEXT_ALLOCATED) )
-        return;
     xfree(core2_vpmu_cxt->pmu_enable);
     xfree(vpmu->context);
     if ( cpu_has_vmx_msr_bitmap )
diff --git a/xen/arch/x86/hvm/vpmu.c b/xen/arch/x86/hvm/vpmu.c
index 1df74c2..37f0d9f 100644
--- a/xen/arch/x86/hvm/vpmu.c
+++ b/xen/arch/x86/hvm/vpmu.c
@@ -247,10 +247,30 @@ void vpmu_initialise(struct vcpu *v)
     }
 }
 
+static void vpmu_clear_last(void *arg)
+{
+    if ( this_cpu(last_vcpu) == arg )
+        this_cpu(last_vcpu) = NULL;
+}
+
 void vpmu_destroy(struct vcpu *v)
 {
     struct vpmu_struct *vpmu = vcpu_vpmu(v);
 
+    if ( !vpmu_is_set(vpmu, VPMU_CONTEXT_ALLOCATED) )
+        return;
+
+    /*
+     * Need to clear last_vcpu in case it points to v.
+     * We can check here non-atomically whether it is 'v' since
+     * last_vcpu can never become 'v' again at this point.
+     * We will test it again in vpmu_clear_last() with interrupts
+     * disabled to make sure we don't clear someone else.
+     */
+    if ( per_cpu(last_vcpu, vpmu->last_pcpu) == v )
+        on_selected_cpus(cpumask_of(vpmu->last_pcpu),
+                         vpmu_clear_last, v, 1);
+
     if ( vpmu->arch_vpmu_ops && vpmu->arch_vpmu_ops->arch_vpmu_destroy )
         vpmu->arch_vpmu_ops->arch_vpmu_destroy(v);
 }
diff --git a/xen/arch/x86/io_apic.c b/xen/arch/x86/io_apic.c
index 6f8f62c..01f816b 100644
--- a/xen/arch/x86/io_apic.c
+++ b/xen/arch/x86/io_apic.c
@@ -33,6 +33,7 @@
 #include <asm/smp.h>
 #include <asm/desc.h>
 #include <asm/msi.h>
+#include <asm/setup.h>
 #include <mach_apic.h>
 #include <io_ports.h>
 #include <public/physdev.h>
@@ -2606,3 +2607,14 @@ void __init init_ioapic_mappings(void)
            nr_irqs_gsi, nr_irqs - nr_irqs_gsi);
 }
 
+unsigned int arch_hwdom_irqs(domid_t domid)
+{
+    unsigned int n = fls(num_present_cpus());
+
+    if ( !domid )
+        n = min(n, dom0_max_vcpus());
+    n = min(nr_irqs_gsi + n * NR_DYNAMIC_VECTORS, nr_irqs);
+    printk("Dom%d has maximum %u PIRQs\n", domid, n);
+
+    return n;
+}
diff --git a/xen/arch/x86/microcode_amd.c b/xen/arch/x86/microcode_amd.c
index b68cf93..f79b397 100644
--- a/xen/arch/x86/microcode_amd.c
+++ b/xen/arch/x86/microcode_amd.c
@@ -331,12 +331,17 @@ static int container_fast_forward(const void *data, size_t size_left, size_t *of
              header[1] == UCODE_EQUIV_CPU_TABLE_TYPE )
             break;
 
+        if ( header[0] != UCODE_UCODE_TYPE )
+            return -EINVAL;
         size = header[1] + SECTION_HDR_SIZE;
         if ( size < PATCH_HDR_SIZE || size_left < size )
             return -EINVAL;
 
         size_left -= size;
         *offset += size;
+
+        if ( !size_left )
+            return -ENODATA;
     }
 
     return 0;
@@ -386,10 +391,6 @@ static int cpu_request_microcode(int cpu, const void *buf, size_t bufsize)
             break;
         }
 
-        if ( find_equiv_cpu_id(mc_amd->equiv_cpu_table, current_cpu_id,
-                               &equiv_cpu_id) )
-                break;
-
         /*
          * Could happen as we advance 'offset' early
          * in install_equiv_cpu_table
@@ -401,7 +402,16 @@ static int cpu_request_microcode(int cpu, const void *buf, size_t bufsize)
             break;
         }
 
+        if ( find_equiv_cpu_id(mc_amd->equiv_cpu_table, current_cpu_id,
+                               &equiv_cpu_id) )
+            break;
+
         error = container_fast_forward(buf, bufsize - offset, &offset);
+        if ( error == -ENODATA )
+        {
+            ASSERT(offset == bufsize);
+            break;
+        }
         if ( error )
         {
             printk(KERN_ERR "microcode: CPU%d incorrect or corrupt container file\n"
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 522c43d..6e9c2c0 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -4661,9 +4661,8 @@ int xenmem_add_to_physmap_one(
 long arch_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
 {
     int rc;
-    int op = cmd & MEMOP_CMD_MASK;
 
-    switch ( op )
+    switch ( cmd )
     {
     case XENMEM_set_memory_map:
     {
@@ -4837,7 +4836,7 @@ long arch_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
         if ( d == NULL )
             return -ESRCH;
 
-        if ( op == XENMEM_set_pod_target )
+        if ( cmd == XENMEM_set_pod_target )
             rc = xsm_set_pod_target(XSM_PRIV, d);
         else
             rc = xsm_get_pod_target(XSM_PRIV, d);
@@ -4845,7 +4844,7 @@ long arch_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
         if ( rc != 0 )
             goto pod_target_out_unlock;
 
-        if ( op == XENMEM_set_pod_target )
+        if ( cmd == XENMEM_set_pod_target )
         {
             if ( target.target_pages > d->max_pages )
             {
@@ -4859,7 +4858,7 @@ long arch_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
         if ( rc == -ERESTART )
         {
             rc = hypercall_create_continuation(
-                __HYPERVISOR_memory_op, "lh", op, arg);
+                __HYPERVISOR_memory_op, "lh", cmd, arg);
         }
         else if ( rc >= 0 )
         {
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 73e95c6..c27c49c 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -1187,6 +1187,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
     }
 
     vm_init();
+    console_init_ring();
     vesa_init();
 
     softirq_init();
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 10fc2ca..3cd8746 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -3168,7 +3168,6 @@ static void nmi_mce_softirq(void)
     int cpu = smp_processor_id();
     struct softirq_trap *st = &per_cpu(softirq_trap, cpu);
 
-    BUG_ON(st == NULL);
     BUG_ON(st->vcpu == NULL);
 
     /* Set the tmp value unconditionally, so that
@@ -3233,7 +3232,7 @@ static void nmi_hwdom_report(unsigned int reason_idx)
 {
     struct domain *d = hardware_domain;
 
-    if ( (d == NULL) || (d->vcpu == NULL) || (d->vcpu[0] == NULL) )
+    if ( !d || !d->vcpu || !d->vcpu[0] || !is_pv_domain(d) /* PVH fixme */ )
         return;
 
     set_bit(reason_idx, nmi_reason(d));
@@ -3674,7 +3673,6 @@ int send_guest_trap(struct domain *d, uint16_t vcpuid, unsigned int trap_nr)
 
         if ( !test_and_set_bool(v->mce_pending) ) {
                 st->domain = d;
-                st->vcpu = v;
                 st->processor = v->processor;
 
                 /* not safe to wake up a vcpu here */
diff --git a/xen/arch/x86/x86_64/compat/mm.c b/xen/arch/x86/x86_64/compat/mm.c
index dce3f1f..f90f611 100644
--- a/xen/arch/x86/x86_64/compat/mm.c
+++ b/xen/arch/x86/x86_64/compat/mm.c
@@ -53,9 +53,8 @@ int compat_arch_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
     compat_pfn_t mfn;
     unsigned int i;
     int rc = 0;
-    int op = cmd & MEMOP_CMD_MASK;
 
-    switch ( op )
+    switch ( cmd )
     {
     case XENMEM_set_memory_map:
     {
@@ -192,7 +191,7 @@ int compat_arch_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
         xen_mem_event_op_t meo;
         if ( copy_from_guest(&meo, arg, 1) )
             return -EFAULT;
-        rc = do_mem_event_op(op, meo.domain, (void *) &meo);
+        rc = do_mem_event_op(cmd, meo.domain, &meo);
         if ( !rc && __copy_to_guest(arg, &meo, 1) )
             return -EFAULT;
         break;
@@ -205,7 +204,7 @@ int compat_arch_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
             return -EFAULT;
         if ( mso.op == XENMEM_sharing_op_audit )
             return mem_sharing_audit(); 
-        rc = do_mem_event_op(op, mso.domain, (void *) &mso);
+        rc = do_mem_event_op(cmd, mso.domain, &mso);
         if ( !rc && __copy_to_guest(arg, &mso, 1) )
             return -EFAULT;
         break;
diff --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c
index 8e5a1a1..d631aee 100644
--- a/xen/arch/x86/x86_64/mm.c
+++ b/xen/arch/x86/x86_64/mm.c
@@ -906,9 +906,8 @@ long subarch_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
     xen_pfn_t mfn, last_mfn;
     unsigned int i;
     long rc = 0;
-    int op = cmd & MEMOP_CMD_MASK;
 
-    switch ( op )
+    switch ( cmd )
     {
     case XENMEM_machphys_mfn_list:
         if ( copy_from_guest(&xmml, arg, 1) )
@@ -989,7 +988,7 @@ long subarch_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
         xen_mem_event_op_t meo;
         if ( copy_from_guest(&meo, arg, 1) )
             return -EFAULT;
-        rc = do_mem_event_op(op, meo.domain, (void *) &meo);
+        rc = do_mem_event_op(cmd, meo.domain, &meo);
         if ( !rc && __copy_to_guest(arg, &meo, 1) )
             return -EFAULT;
         break;
@@ -1002,7 +1001,7 @@ long subarch_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
             return -EFAULT;
         if ( mso.op == XENMEM_sharing_op_audit )
             return mem_sharing_audit(); 
-        rc = do_mem_event_op(op, mso.domain, (void *) &mso);
+        rc = do_mem_event_op(cmd, mso.domain, &mso);
         if ( !rc && __copy_to_guest(arg, &mso, 1) )
             return -EFAULT;
         break;
diff --git a/xen/common/compat/grant_table.c b/xen/common/compat/grant_table.c
index 0368289..f8c60a1 100644
--- a/xen/common/compat/grant_table.c
+++ b/xen/common/compat/grant_table.c
@@ -65,6 +65,8 @@ int compat_grant_table_op(unsigned int cmd,
 
     set_xen_guest_handle(cnt_uop, NULL);
     cmd_op = cmd & GNTTABOP_CMD_MASK;
+    if ( cmd_op != GNTTABOP_cache_flush )
+        cmd_op = cmd;
     switch ( cmd_op )
     {
 #define CASE(name) \
diff --git a/xen/common/domain.c b/xen/common/domain.c
index 4a62c1d..336e9ea 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -231,14 +231,14 @@ static int late_hwdom_init(struct domain *d)
 #endif
 }
 
-static unsigned int __read_mostly extra_dom0_irqs = 256;
+static unsigned int __read_mostly extra_hwdom_irqs;
 static unsigned int __read_mostly extra_domU_irqs = 32;
 static void __init parse_extra_guest_irqs(const char *s)
 {
     if ( isdigit(*s) )
         extra_domU_irqs = simple_strtoul(s, &s, 0);
     if ( *s == ',' && isdigit(*++s) )
-        extra_dom0_irqs = simple_strtoul(s, &s, 0);
+        extra_hwdom_irqs = simple_strtoul(s, &s, 0);
 }
 custom_param("extra_guest_irqs", parse_extra_guest_irqs);
 
@@ -326,7 +326,8 @@ struct domain *domain_create(
         if ( !is_hardware_domain(d) )
             d->nr_pirqs = nr_static_irqs + extra_domU_irqs;
         else
-            d->nr_pirqs = nr_static_irqs + extra_dom0_irqs;
+            d->nr_pirqs = extra_hwdom_irqs ? nr_static_irqs + extra_hwdom_irqs
+                                           : arch_hwdom_irqs(domid);
         if ( d->nr_pirqs > nr_irqs )
             d->nr_pirqs = nr_irqs;
 
diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index f15dcfe..8bca6da 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -981,18 +981,21 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
 
     case XEN_DOMCTL_irq_permission:
     {
-        unsigned int pirq = op->u.irq_permission.pirq;
+        unsigned int pirq = op->u.irq_permission.pirq, irq;
         int allow = op->u.irq_permission.allow_access;
 
-        if ( pirq >= d->nr_pirqs )
+        if ( pirq >= current->domain->nr_pirqs )
+        {
             ret = -EINVAL;
-        else if ( !pirq_access_permitted(current->domain, pirq) ||
-                  xsm_irq_permission(XSM_HOOK, d, pirq, allow) )
+            break;
+        }
+        irq = pirq_access_permitted(current->domain, pirq);
+        if ( !irq || xsm_irq_permission(XSM_HOOK, d, irq, allow) )
             ret = -EPERM;
         else if ( allow )
-            ret = pirq_permit_access(d, pirq);
+            ret = irq_permit_access(d, irq);
         else
-            ret = pirq_deny_access(d, pirq);
+            ret = irq_deny_access(d, irq);
     }
     break;
 
diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
index c68efdb..ac6881e 100644
--- a/xen/common/efi/boot.c
+++ b/xen/common/efi/boot.c
@@ -311,6 +311,7 @@ static unsigned int __init get_argv(unsigned int argc, CHAR16 **argv,
                 ++argc;
             else if ( prev && wstrcmp(prev, L"--") == 0 )
             {
+                --argv;
                 if ( options )
                     *options = cmdline;
                 break;
diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c
index 8fba923..fe52b63 100644
--- a/xen/common/grant_table.c
+++ b/xen/common/grant_table.c
@@ -62,6 +62,12 @@ integer_param("gnttab_max_frames", max_grant_frames);
 static unsigned int __read_mostly max_maptrack_frames;
 integer_param("gnttab_max_maptrack_frames", max_maptrack_frames);
 
+/*
+ * Note that the three values below are effectively part of the ABI, even if
+ * we don't need to make them a formal part of it: A guest suspended for
+ * migration in the middle of a continuation would fail to work if resumed on
+ * a hypervisor using different values.
+ */
 #define GNTTABOP_CONTINUATION_ARG_SHIFT 12
 #define GNTTABOP_CMD_MASK               ((1<<GNTTABOP_CONTINUATION_ARG_SHIFT)-1)
 #define GNTTABOP_ARG_MASK               (~GNTTABOP_CMD_MASK)
@@ -2624,9 +2630,12 @@ do_grant_table_op(
     
     if ( (int)count < 0 )
         return -EINVAL;
+
+    if ( (cmd &= GNTTABOP_CMD_MASK) != GNTTABOP_cache_flush && opaque_in )
+        return -ENOSYS;
     
     rc = -EFAULT;
-    switch ( cmd &= GNTTABOP_CMD_MASK )
+    switch ( cmd )
     {
     case GNTTABOP_map_grant_ref:
     {
diff --git a/xen/common/mem_access.c b/xen/common/mem_access.c
index 6c2724b..d8aac5f 100644
--- a/xen/common/mem_access.c
+++ b/xen/common/mem_access.c
@@ -58,6 +58,7 @@ void mem_access_resume(struct domain *d)
 int mem_access_memop(unsigned long cmd,
                      XEN_GUEST_HANDLE_PARAM(xen_mem_access_op_t) arg)
 {
+    unsigned long start_iter = cmd & ~MEMOP_CMD_MASK;
     long rc;
     xen_mem_access_op_t mao;
     struct domain *d;
@@ -84,14 +85,16 @@ int mem_access_memop(unsigned long cmd,
     switch ( mao.op )
     {
     case XENMEM_access_op_resume:
-        mem_access_resume(d);
-        rc = 0;
+        if ( unlikely(start_iter) )
+            rc = -ENOSYS;
+        else
+        {
+            mem_access_resume(d);
+            rc = 0;
+        }
         break;
 
     case XENMEM_access_op_set_access:
-    {
-        unsigned long start_iter = cmd & ~MEMOP_CMD_MASK;
-
         rc = -EINVAL;
         if ( (mao.pfn != ~0ull) &&
              (mao.nr < start_iter ||
@@ -108,12 +111,15 @@ int mem_access_memop(unsigned long cmd,
                                                XENMEM_access_op | rc, arg);
         }
         break;
-    }
 
     case XENMEM_access_op_get_access:
     {
         xenmem_access_t access;
 
+        rc = -ENOSYS;
+        if ( unlikely(start_iter) )
+            break;
+
         rc = -EINVAL;
         if ( (mao.pfn > domain_get_maximum_gpfn(d)) && mao.pfn != ~0ull )
             break;
diff --git a/xen/common/memory.c b/xen/common/memory.c
index 9f21bd3..234dae6 100644
--- a/xen/common/memory.c
+++ b/xen/common/memory.c
@@ -779,16 +779,25 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
         break;
 
     case XENMEM_exchange:
+        if ( unlikely(start_extent) )
+            return -ENOSYS;
+
         rc = memory_exchange(guest_handle_cast(arg, xen_memory_exchange_t));
         break;
 
     case XENMEM_maximum_ram_page:
+        if ( unlikely(start_extent) )
+            return -ENOSYS;
+
         rc = max_page;
         break;
 
     case XENMEM_current_reservation:
     case XENMEM_maximum_reservation:
     case XENMEM_maximum_gpfn:
+        if ( unlikely(start_extent) )
+            return -ENOSYS;
+
         if ( copy_from_guest(&domid, arg, 1) )
             return -EFAULT;
 
@@ -912,6 +921,9 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
         struct page_info *page;
         struct domain *d;
 
+        if ( unlikely(start_extent) )
+            return -ENOSYS;
+
         if ( copy_from_guest(&xrfp, arg, 1) )
             return -EFAULT;
 
@@ -945,6 +957,9 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
         break;
 
     case XENMEM_claim_pages:
+        if ( unlikely(start_extent) )
+            return -ENOSYS;
+
         if ( copy_from_guest(&reservation, arg, 1) )
             return -EFAULT;
 
@@ -977,6 +992,9 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
         unsigned int dom_vnodes, dom_vranges, dom_vcpus;
         struct vnuma_info tmp;
 
+        if ( unlikely(start_extent) )
+            return -ENOSYS;
+
         /*
          * Guest passes nr_vnodes, number of regions and nr_vcpus thus
          * we know how much memory guest has allocated.
diff --git a/xen/common/spinlock.c b/xen/common/spinlock.c
index 575cc6d..f9f19a8 100644
--- a/xen/common/spinlock.c
+++ b/xen/common/spinlock.c
@@ -271,112 +271,151 @@ void _spin_unlock_recursive(spinlock_t *lock)
 
 void _read_lock(rwlock_t *lock)
 {
+    uint32_t x;
+
     check_lock(&lock->debug);
-    while ( unlikely(!_raw_read_trylock(&lock->raw)) )
-    {
-        while ( likely(_raw_rw_is_write_locked(&lock->raw)) )
+    do {
+        while ( (x = lock->lock) & RW_WRITE_FLAG )
             cpu_relax();
-    }
+    } while ( cmpxchg(&lock->lock, x, x+1) != x );
     preempt_disable();
 }
 
 void _read_lock_irq(rwlock_t *lock)
 {
+    uint32_t x;
+
     ASSERT(local_irq_is_enabled());
     local_irq_disable();
     check_lock(&lock->debug);
-    while ( unlikely(!_raw_read_trylock(&lock->raw)) )
-    {
-        local_irq_enable();
-        while ( likely(_raw_rw_is_write_locked(&lock->raw)) )
-            cpu_relax();
-        local_irq_disable();
-    }
+    do {
+        if ( (x = lock->lock) & RW_WRITE_FLAG )
+        {
+            local_irq_enable();
+            while ( (x = lock->lock) & RW_WRITE_FLAG )
+                cpu_relax();
+            local_irq_disable();
+        }
+    } while ( cmpxchg(&lock->lock, x, x+1) != x );
     preempt_disable();
 }
 
 unsigned long _read_lock_irqsave(rwlock_t *lock)
 {
+    uint32_t x;
     unsigned long flags;
+
     local_irq_save(flags);
     check_lock(&lock->debug);
-    while ( unlikely(!_raw_read_trylock(&lock->raw)) )
-    {
-        local_irq_restore(flags);
-        while ( likely(_raw_rw_is_write_locked(&lock->raw)) )
-            cpu_relax();
-        local_irq_save(flags);
-    }
+    do {
+        if ( (x = lock->lock) & RW_WRITE_FLAG )
+        {
+            local_irq_restore(flags);
+            while ( (x = lock->lock) & RW_WRITE_FLAG )
+                cpu_relax();
+            local_irq_save(flags);
+        }
+    } while ( cmpxchg(&lock->lock, x, x+1) != x );
     preempt_disable();
     return flags;
 }
 
 int _read_trylock(rwlock_t *lock)
 {
+    uint32_t x;
+
     check_lock(&lock->debug);
-    if ( !_raw_read_trylock(&lock->raw) )
-        return 0;
+    do {
+        if ( (x = lock->lock) & RW_WRITE_FLAG )
+            return 0;
+    } while ( cmpxchg(&lock->lock, x, x+1) != x );
     preempt_disable();
     return 1;
 }
 
 void _read_unlock(rwlock_t *lock)
 {
+    uint32_t x, y;
+
     preempt_enable();
-    _raw_read_unlock(&lock->raw);
+    x = lock->lock;
+    while ( (y = cmpxchg(&lock->lock, x, x-1)) != x )
+        x = y;
 }
 
 void _read_unlock_irq(rwlock_t *lock)
 {
-    preempt_enable();
-    _raw_read_unlock(&lock->raw);
+    _read_unlock(lock);
     local_irq_enable();
 }
 
 void _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
 {
-    preempt_enable();
-    _raw_read_unlock(&lock->raw);
+    _read_unlock(lock);
     local_irq_restore(flags);
 }
 
 void _write_lock(rwlock_t *lock)
 {
+    uint32_t x;
+
     check_lock(&lock->debug);
-    while ( unlikely(!_raw_write_trylock(&lock->raw)) )
-    {
-        while ( likely(_raw_rw_is_locked(&lock->raw)) )
+    do {
+        while ( (x = lock->lock) & RW_WRITE_FLAG )
             cpu_relax();
+    } while ( cmpxchg(&lock->lock, x, x|RW_WRITE_FLAG) != x );
+    while ( x != 0 )
+    {
+        cpu_relax();
+        x = lock->lock & ~RW_WRITE_FLAG;
     }
     preempt_disable();
 }
 
 void _write_lock_irq(rwlock_t *lock)
 {
+    uint32_t x;
+
     ASSERT(local_irq_is_enabled());
     local_irq_disable();
     check_lock(&lock->debug);
-    while ( unlikely(!_raw_write_trylock(&lock->raw)) )
+    do {
+        if ( (x = lock->lock) & RW_WRITE_FLAG )
+        {
+            local_irq_enable();
+            while ( (x = lock->lock) & RW_WRITE_FLAG )
+                cpu_relax();
+            local_irq_disable();
+        }
+    } while ( cmpxchg(&lock->lock, x, x|RW_WRITE_FLAG) != x );
+    while ( x != 0 )
     {
-        local_irq_enable();
-        while ( likely(_raw_rw_is_locked(&lock->raw)) )
-            cpu_relax();
-        local_irq_disable();
+        cpu_relax();
+        x = lock->lock & ~RW_WRITE_FLAG;
     }
     preempt_disable();
 }
 
 unsigned long _write_lock_irqsave(rwlock_t *lock)
 {
+    uint32_t x;
     unsigned long flags;
+
     local_irq_save(flags);
     check_lock(&lock->debug);
-    while ( unlikely(!_raw_write_trylock(&lock->raw)) )
+    do {
+        if ( (x = lock->lock) & RW_WRITE_FLAG )
+        {
+            local_irq_restore(flags);
+            while ( (x = lock->lock) & RW_WRITE_FLAG )
+                cpu_relax();
+            local_irq_save(flags);
+        }
+    } while ( cmpxchg(&lock->lock, x, x|RW_WRITE_FLAG) != x );
+    while ( x != 0 )
     {
-        local_irq_restore(flags);
-        while ( likely(_raw_rw_is_locked(&lock->raw)) )
-            cpu_relax();
-        local_irq_save(flags);
+        cpu_relax();
+        x = lock->lock & ~RW_WRITE_FLAG;
     }
     preempt_disable();
     return flags;
@@ -384,9 +423,13 @@ unsigned long _write_lock_irqsave(rwlock_t *lock)
 
 int _write_trylock(rwlock_t *lock)
 {
+    uint32_t x;
+
     check_lock(&lock->debug);
-    if ( !_raw_write_trylock(&lock->raw) )
-        return 0;
+    do {
+        if ( (x = lock->lock) != 0 )
+            return 0;
+    } while ( cmpxchg(&lock->lock, x, x|RW_WRITE_FLAG) != x );
     preempt_disable();
     return 1;
 }
@@ -394,33 +437,32 @@ int _write_trylock(rwlock_t *lock)
 void _write_unlock(rwlock_t *lock)
 {
     preempt_enable();
-    _raw_write_unlock(&lock->raw);
+    if ( cmpxchg(&lock->lock, RW_WRITE_FLAG, 0) != RW_WRITE_FLAG )
+        BUG();
 }
 
 void _write_unlock_irq(rwlock_t *lock)
 {
-    preempt_enable();
-    _raw_write_unlock(&lock->raw);
+    _write_unlock(lock);
     local_irq_enable();
 }
 
 void _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
 {
-    preempt_enable();
-    _raw_write_unlock(&lock->raw);
+    _write_unlock(lock);
     local_irq_restore(flags);
 }
 
 int _rw_is_locked(rwlock_t *lock)
 {
     check_lock(&lock->debug);
-    return _raw_rw_is_locked(&lock->raw);
+    return (lock->lock != 0); /* anyone in critical section? */
 }
 
 int _rw_is_write_locked(rwlock_t *lock)
 {
     check_lock(&lock->debug);
-    return _raw_rw_is_write_locked(&lock->raw);
+    return (lock->lock == RW_WRITE_FLAG); /* writer in critical section? */
 }
 
 #ifdef LOCK_PROFILE
diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c
index 2f03259..0b8d3d4 100644
--- a/xen/drivers/char/console.c
+++ b/xen/drivers/char/console.c
@@ -744,15 +744,14 @@ void __init console_init_preirq(void)
     }
 }
 
-void __init console_init_postirq(void)
+void __init console_init_ring(void)
 {
     char *ring;
     unsigned int i, order, memflags;
-
-    serial_init_postirq();
+    unsigned long flags;
 
     if ( !opt_conring_size )
-        opt_conring_size = num_present_cpus() << (9 + xenlog_lower_thresh);
+        return;
 
     order = get_order_from_bytes(max(opt_conring_size, conring_size));
     memflags = MEMF_bits(crashinfo_maxaddr_bits);
@@ -763,17 +762,30 @@ void __init console_init_postirq(void)
     }
     opt_conring_size = PAGE_SIZE << order;
 
-    spin_lock_irq(&console_lock);
+    spin_lock_irqsave(&console_lock, flags);
     for ( i = conringc ; i != conringp; i++ )
         ring[i & (opt_conring_size - 1)] = conring[i & (conring_size - 1)];
     conring = ring;
     smp_wmb(); /* Allow users of console_force_unlock() to see larger buffer. */
     conring_size = opt_conring_size;
-    spin_unlock_irq(&console_lock);
+    spin_unlock_irqrestore(&console_lock, flags);
 
     printk("Allocated console ring of %u KiB.\n", opt_conring_size >> 10);
 }
 
+void __init console_init_postirq(void)
+{
+    serial_init_postirq();
+
+    if ( conring != _conring )
+        return;
+
+    if ( !opt_conring_size )
+        opt_conring_size = num_present_cpus() << (9 + xenlog_lower_thresh);
+
+    console_init_ring();
+}
+
 void __init console_endboot(void)
 {
     int i, j;
diff --git a/xen/drivers/char/omap-uart.c b/xen/drivers/char/omap-uart.c
index a798b8d..16d1454 100644
--- a/xen/drivers/char/omap-uart.c
+++ b/xen/drivers/char/omap-uart.c
@@ -195,6 +195,9 @@ static void __init omap_uart_init_preirq(struct serial_port *port)
     omap_write(uart, UART_MCR, UART_MCR_DTR|UART_MCR_RTS);
 
     omap_write(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_16X_MODE);
+
+    /* setup iddle mode */
+    omap_write(uart, UART_SYSC, OMAP_UART_SYSC_DEF_CONF);
 }
 
 static void __init omap_uart_init_postirq(struct serial_port *port)
diff --git a/xen/drivers/passthrough/io.c b/xen/drivers/passthrough/io.c
index ae050df..4cd32b5 100644
--- a/xen/drivers/passthrough/io.c
+++ b/xen/drivers/passthrough/io.c
@@ -20,123 +20,14 @@
 
 #include <xen/event.h>
 #include <xen/iommu.h>
-#include <xen/cpu.h>
 #include <xen/irq.h>
 #include <asm/hvm/irq.h>
 #include <asm/hvm/iommu.h>
 #include <asm/hvm/support.h>
 #include <xen/hvm/irq.h>
+#include <xen/tasklet.h>
 
-static DEFINE_PER_CPU(struct list_head, dpci_list);
-
-/*
- * These two bit states help to safely schedule, deschedule, and wait until
- * the softirq has finished.
- *
- * The semantics behind these two bits is as follow:
- *  - STATE_SCHED - whoever modifies it has to ref-count the domain (->dom).
- *  - STATE_RUN - only softirq is allowed to set and clear it. If it has
- *      been set hvm_dirq_assist will RUN with a saved value of the
- *      'struct domain' copied from 'pirq_dpci->dom' before STATE_RUN was set.
- *
- * The usual states are: STATE_SCHED(set) -> STATE_RUN(set) ->
- * STATE_SCHED(unset) -> STATE_RUN(unset).
- *
- * However the states can also diverge such as: STATE_SCHED(set) ->
- * STATE_SCHED(unset) -> STATE_RUN(set) -> STATE_RUN(unset). That means
- * the 'hvm_dirq_assist' never run and that the softirq did not do any
- * ref-counting.
- */
-
-enum {
-    STATE_SCHED,
-    STATE_RUN
-};
-
-/*
- * This can be called multiple times, but the softirq is only raised once.
- * That is until the STATE_SCHED state has been cleared. The state can be
- * cleared by: the 'dpci_softirq' (when it has executed 'hvm_dirq_assist'),
- * or by 'pt_pirq_softirq_reset' (which will try to clear the state before
- * the softirq had a chance to run).
- */
-static void raise_softirq_for(struct hvm_pirq_dpci *pirq_dpci)
-{
-    unsigned long flags;
-
-    if ( test_and_set_bit(STATE_SCHED, &pirq_dpci->state) )
-        return;
-
-    get_knownalive_domain(pirq_dpci->dom);
-
-    local_irq_save(flags);
-    list_add_tail(&pirq_dpci->softirq_list, &this_cpu(dpci_list));
-    local_irq_restore(flags);
-
-    raise_softirq(HVM_DPCI_SOFTIRQ);
-}
-
-/*
- * If we are racing with softirq_dpci (STATE_SCHED) we return
- * true. Otherwise we return false.
- *
- * If it is false, it is the callers responsibility to make sure
- * that the softirq (with the event_lock dropped) has ran.
- */
-bool_t pt_pirq_softirq_active(struct hvm_pirq_dpci *pirq_dpci)
-{
-    if ( pirq_dpci->state & ((1 << STATE_RUN) | (1 << STATE_SCHED)) )
-        return 1;
-
-    /*
-     * If in the future we would call 'raise_softirq_for' right away
-     * after 'pt_pirq_softirq_active' we MUST reset the list (otherwise it
-     * might have stale data).
-     */
-    return 0;
-}
-
-/*
- * Reset the pirq_dpci->dom parameter to NULL.
- *
- * This function checks the different states to make sure it can do it
- * at the right time. If it unschedules the 'hvm_dirq_assist' from running
- * it also refcounts (which is what the softirq would have done) properly.
- */
-static void pt_pirq_softirq_reset(struct hvm_pirq_dpci *pirq_dpci)
-{
-    struct domain *d = pirq_dpci->dom;
-
-    ASSERT(spin_is_locked(&d->event_lock));
-
-    switch ( cmpxchg(&pirq_dpci->state, 1 << STATE_SCHED, 0) )
-    {
-    case (1 << STATE_SCHED):
-        /*
-         * We are going to try to de-schedule the softirq before it goes in
-         * STATE_RUN. Whoever clears STATE_SCHED MUST refcount the 'dom'.
-         */
-        put_domain(d);
-        /* fallthrough. */
-    case (1 << STATE_RUN):
-    case (1 << STATE_RUN) | (1 << STATE_SCHED):
-        /*
-         * The reason it is OK to reset 'dom' when STATE_RUN bit is set is due
-         * to a shortcut the 'dpci_softirq' implements. It stashes the 'dom'
-         * in local variable before it sets STATE_RUN - and therefore will not
-         * dereference '->dom' which would crash.
-         */
-        pirq_dpci->dom = NULL;
-        break;
-    }
-    /*
-     * Inhibit 'hvm_dirq_assist' from doing anything useful and at worst
-     * calling 'set_timer' which will blow up (as we have called kill_timer
-     * or never initialized it). Note that we hold the lock that
-     * 'hvm_dirq_assist' could be spinning on.
-     */
-    pirq_dpci->masked = 0;
-}
+static void hvm_dirq_assist(unsigned long _d);
 
 bool_t pt_irq_need_timer(uint32_t flags)
 {
@@ -210,7 +101,6 @@ int pt_irq_create_bind(
     if ( pirq < 0 || pirq >= d->nr_pirqs )
         return -EINVAL;
 
- restart:
     spin_lock(&d->event_lock);
 
     hvm_irq_dpci = domain_get_irq_dpci(d);
@@ -224,6 +114,9 @@ int pt_irq_create_bind(
             spin_unlock(&d->event_lock);
             return -ENOMEM;
         }
+        softirq_tasklet_init(
+            &hvm_irq_dpci->dirq_tasklet,
+            hvm_dirq_assist, (unsigned long)d);
         for ( i = 0; i < NR_HVM_IRQS; i++ )
             INIT_LIST_HEAD(&hvm_irq_dpci->girq[i]);
 
@@ -238,21 +131,6 @@ int pt_irq_create_bind(
     }
     pirq_dpci = pirq_dpci(info);
 
-    /*
-     * A crude 'while' loop with us dropping the spinlock and giving
-     * the softirq_dpci a chance to run.
-     * We MUST check for this condition as the softirq could be scheduled
-     * and hasn't run yet. Note that this code replaced tasklet_kill which
-     * would have spun forever and would do the same thing (wait to flush out
-     * outstanding hvm_dirq_assist calls.
-     */
-    if ( pt_pirq_softirq_active(pirq_dpci) )
-    {
-        spin_unlock(&d->event_lock);
-        cpu_relax();
-        goto restart;
-    }
-
     switch ( pt_irq_bind->irq_type )
     {
     case PT_IRQ_TYPE_MSI:
@@ -266,40 +144,18 @@ int pt_irq_create_bind(
                                HVM_IRQ_DPCI_GUEST_MSI;
             pirq_dpci->gmsi.gvec = pt_irq_bind->u.msi.gvec;
             pirq_dpci->gmsi.gflags = pt_irq_bind->u.msi.gflags;
-            /*
-             * 'pt_irq_create_bind' can be called after 'pt_irq_destroy_bind'.
-             * The 'pirq_cleanup_check' which would free the structure is only
-             * called if the event channel for the PIRQ is active. However
-             * OS-es that use event channels usually bind PIRQs to eventds
-             * and unbind them before calling 'pt_irq_destroy_bind' - with the
-             * result that we re-use the 'dpci' structure. This can be
-             * reproduced with unloading and loading the driver for a device.
-             *
-             * As such on every 'pt_irq_create_bind' call we MUST set it.
-             */
-            pirq_dpci->dom = d;
             /* bind after hvm_irq_dpci is setup to avoid race with irq handler*/
             rc = pirq_guest_bind(d->vcpu[0], info, 0);
             if ( rc == 0 && pt_irq_bind->u.msi.gtable )
             {
                 rc = msixtbl_pt_register(d, info, pt_irq_bind->u.msi.gtable);
                 if ( unlikely(rc) )
-                {
                     pirq_guest_unbind(d, info);
-                    /*
-                     * Between 'pirq_guest_bind' and before 'pirq_guest_unbind'
-                     * an interrupt can be scheduled. No more of them are going
-                     * to be scheduled but we must deal with the one that may be
-                     * in the queue.
-                     */
-                    pt_pirq_softirq_reset(pirq_dpci);
-                }
             }
             if ( unlikely(rc) )
             {
                 pirq_dpci->gmsi.gflags = 0;
                 pirq_dpci->gmsi.gvec = 0;
-                pirq_dpci->dom = NULL;
                 pirq_dpci->flags = 0;
                 pirq_cleanup_check(info, d);
                 spin_unlock(&d->event_lock);
@@ -376,7 +232,6 @@ int pt_irq_create_bind(
         {
             unsigned int share;
 
-            /* MUST be set, as the pirq_dpci can be re-used. */
             pirq_dpci->dom = d;
             if ( pt_irq_bind->irq_type == PT_IRQ_TYPE_MSI_TRANSLATE )
             {
@@ -403,10 +258,6 @@ int pt_irq_create_bind(
             {
                 if ( pt_irq_need_timer(pirq_dpci->flags) )
                     kill_timer(&pirq_dpci->timer);
-                /*
-                 * There is no path for __do_IRQ to schedule softirq as
-                 * IRQ_GUEST is not set. As such we can reset 'dom' directly.
-                 */
                 pirq_dpci->dom = NULL;
                 list_del(&girq->list);
                 list_del(&digl->list);
@@ -540,13 +391,8 @@ int pt_irq_destroy_bind(
         msixtbl_pt_unregister(d, pirq);
         if ( pt_irq_need_timer(pirq_dpci->flags) )
             kill_timer(&pirq_dpci->timer);
+        pirq_dpci->dom   = NULL;
         pirq_dpci->flags = 0;
-        /*
-         * See comment in pt_irq_create_bind's PT_IRQ_TYPE_MSI before the
-         * call to pt_pirq_softirq_reset.
-         */
-        pt_pirq_softirq_reset(pirq_dpci);
-
         pirq_cleanup_check(pirq, d);
     }
 
@@ -573,12 +419,7 @@ void pt_pirq_init(struct domain *d, struct hvm_pirq_dpci *dpci)
 
 bool_t pt_pirq_cleanup_check(struct hvm_pirq_dpci *dpci)
 {
-    if ( !dpci->flags && !pt_pirq_softirq_active(dpci) )
-    {
-        dpci->dom = NULL;
-        return 1;
-    }
-    return 0;
+    return !dpci->flags;
 }
 
 int pt_pirq_iterate(struct domain *d,
@@ -618,7 +459,7 @@ int hvm_do_IRQ_dpci(struct domain *d, struct pirq *pirq)
         return 0;
 
     pirq_dpci->masked = 1;
-    raise_softirq_for(pirq_dpci);
+    tasklet_schedule(&dpci->dirq_tasklet);
     return 1;
 }
 
@@ -672,11 +513,9 @@ void hvm_dpci_msi_eoi(struct domain *d, int vector)
     spin_unlock(&d->event_lock);
 }
 
-static void hvm_dirq_assist(struct domain *d, struct hvm_pirq_dpci *pirq_dpci)
+static int _hvm_dirq_assist(struct domain *d, struct hvm_pirq_dpci *pirq_dpci,
+                            void *arg)
 {
-    ASSERT(d->arch.hvm_domain.irq.dpci);
-
-    spin_lock(&d->event_lock);
     if ( test_and_clear_bool(pirq_dpci->masked) )
     {
         struct pirq *pirq = dpci_pirq(pirq_dpci);
@@ -687,17 +526,13 @@ static void hvm_dirq_assist(struct domain *d, struct hvm_pirq_dpci *pirq_dpci)
             send_guest_pirq(d, pirq);
 
             if ( pirq_dpci->flags & HVM_IRQ_DPCI_GUEST_MSI )
-            {
-                spin_unlock(&d->event_lock);
-                return;
-            }
+                return 0;
         }
 
         if ( pirq_dpci->flags & HVM_IRQ_DPCI_GUEST_MSI )
         {
             vmsi_deliver_pirq(d, pirq_dpci);
-            spin_unlock(&d->event_lock);
-            return;
+            return 0;
         }
 
         list_for_each_entry ( digl, &pirq_dpci->digl_list, list )
@@ -710,8 +545,7 @@ static void hvm_dirq_assist(struct domain *d, struct hvm_pirq_dpci *pirq_dpci)
         {
             /* for translated MSI to INTx interrupt, eoi as early as possible */
             __msi_pirq_eoi(pirq_dpci);
-            spin_unlock(&d->event_lock);
-            return;
+            return 0;
         }
 
         /*
@@ -724,6 +558,18 @@ static void hvm_dirq_assist(struct domain *d, struct hvm_pirq_dpci *pirq_dpci)
         ASSERT(pt_irq_need_timer(pirq_dpci->flags));
         set_timer(&pirq_dpci->timer, NOW() + PT_IRQ_TIME_OUT);
     }
+
+    return 0;
+}
+
+static void hvm_dirq_assist(unsigned long _d)
+{
+    struct domain *d = (struct domain *)_d;
+
+    ASSERT(d->arch.hvm_domain.irq.dpci);
+
+    spin_lock(&d->event_lock);
+    pt_pirq_iterate(d, _hvm_dirq_assist, NULL);
     spin_unlock(&d->event_lock);
 }
 
@@ -779,83 +625,3 @@ void hvm_dpci_eoi(struct domain *d, unsigned int guest_gsi,
 unlock:
     spin_unlock(&d->event_lock);
 }
-
-/*
- * Note: 'pt_pirq_softirq_reset' can clear the STATE_SCHED before we get to
- * doing it. If that is the case we let 'pt_pirq_softirq_reset' do ref-counting.
- */
-static void dpci_softirq(void)
-{
-    unsigned int cpu = smp_processor_id();
-    LIST_HEAD(our_list);
-
-    local_irq_disable();
-    list_splice_init(&per_cpu(dpci_list, cpu), &our_list);
-    local_irq_enable();
-
-    while ( !list_empty(&our_list) )
-    {
-        struct hvm_pirq_dpci *pirq_dpci;
-        struct domain *d;
-
-        pirq_dpci = list_entry(our_list.next, struct hvm_pirq_dpci, softirq_list);
-        list_del(&pirq_dpci->softirq_list);
-
-        d = pirq_dpci->dom;
-        smp_mb(); /* 'd' MUST be saved before we set/clear the bits. */
-        if ( test_and_set_bit(STATE_RUN, &pirq_dpci->state) )
-            BUG();
-        /*
-         * The one who clears STATE_SCHED MUST refcount the domain.
-         */
-        if ( test_and_clear_bit(STATE_SCHED, &pirq_dpci->state) )
-        {
-            hvm_dirq_assist(d, pirq_dpci);
-            put_domain(d);
-        }
-        clear_bit(STATE_RUN, &pirq_dpci->state);
-    }
-}
-
-static int cpu_callback(
-    struct notifier_block *nfb, unsigned long action, void *hcpu)
-{
-    unsigned int cpu = (unsigned long)hcpu;
-
-    switch ( action )
-    {
-    case CPU_UP_PREPARE:
-        INIT_LIST_HEAD(&per_cpu(dpci_list, cpu));
-        break;
-    case CPU_UP_CANCELED:
-    case CPU_DEAD:
-        /*
-         * On CPU_DYING this callback is called (on the CPU that is dying)
-         * with an possible HVM_DPIC_SOFTIRQ pending - at which point we can
-         * clear out any outstanding domains (by the virtue of the idle loop
-         * calling the softirq later). In CPU_DEAD case the CPU is deaf and
-         * there are no pending softirqs for us to handle so we can chill.
-         */
-        ASSERT(list_empty(&per_cpu(dpci_list, cpu)));
-        break;
-    }
-
-    return NOTIFY_DONE;
-}
-
-static struct notifier_block cpu_nfb = {
-    .notifier_call = cpu_callback,
-};
-
-static int __init setup_dpci_softirq(void)
-{
-    unsigned int cpu;
-
-    for_each_online_cpu(cpu)
-        INIT_LIST_HEAD(&per_cpu(dpci_list, cpu));
-
-    open_softirq(HVM_DPCI_SOFTIRQ, dpci_softirq);
-    register_cpu_notifier(&cpu_nfb);
-    return 0;
-}
-__initcall(setup_dpci_softirq);
diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
index 78c6977..1eba833 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -767,51 +767,40 @@ static int pci_clean_dpci_irq(struct domain *d,
         xfree(digl);
     }
 
-    return pt_pirq_softirq_active(pirq_dpci) ? -ERESTART : 0;
+    return 0;
 }
 
-static int pci_clean_dpci_irqs(struct domain *d)
+static void pci_clean_dpci_irqs(struct domain *d)
 {
     struct hvm_irq_dpci *hvm_irq_dpci = NULL;
 
     if ( !iommu_enabled )
-        return 0;
+        return;
 
     if ( !is_hvm_domain(d) )
-        return 0;
+        return;
 
     spin_lock(&d->event_lock);
     hvm_irq_dpci = domain_get_irq_dpci(d);
     if ( hvm_irq_dpci != NULL )
     {
-        int ret = pt_pirq_iterate(d, pci_clean_dpci_irq, NULL);
+        tasklet_kill(&hvm_irq_dpci->dirq_tasklet);
 
-        if ( ret )
-        {
-            spin_unlock(&d->event_lock);
-            return ret;
-        }
+        pt_pirq_iterate(d, pci_clean_dpci_irq, NULL);
 
         d->arch.hvm_domain.irq.dpci = NULL;
         free_hvm_irq_dpci(hvm_irq_dpci);
     }
     spin_unlock(&d->event_lock);
-    return 0;
 }
 
-int pci_release_devices(struct domain *d)
+void pci_release_devices(struct domain *d)
 {
     struct pci_dev *pdev;
     u8 bus, devfn;
-    int ret;
 
     spin_lock(&pcidevs_lock);
-    ret = pci_clean_dpci_irqs(d);
-    if ( ret )
-    {
-        spin_unlock(&pcidevs_lock);
-        return ret;
-    }
+    pci_clean_dpci_irqs(d);
     while ( (pdev = pci_get_pdev_by_domain(d, -1, -1, -1)) )
     {
         bus = pdev->bus;
@@ -822,8 +811,6 @@ int pci_release_devices(struct domain *d)
                    PCI_SLOT(devfn), PCI_FUNC(devfn));
     }
     spin_unlock(&pcidevs_lock);
-
-    return 0;
 }
 
 #define PCI_CLASS_BRIDGE_HOST    0x0600
diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c
index 19d8165..2e113d7 100644
--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -258,8 +258,7 @@ static u64 addr_to_dma_page_maddr(struct domain *domain, u64 addr, int alloc)
     struct dma_pte *parent, *pte = NULL;
     int level = agaw_to_level(hd->arch.agaw);
     int offset;
-    u64 pte_maddr = 0, maddr;
-    u64 *vaddr = NULL;
+    u64 pte_maddr = 0;
 
     addr &= (((u64)1) << addr_width) - 1;
     ASSERT(spin_is_locked(&hd->arch.mapping_lock));
@@ -281,19 +280,19 @@ static u64 addr_to_dma_page_maddr(struct domain *domain, u64 addr, int alloc)
         offset = address_level_offset(addr, level);
         pte = &parent[offset];
 
-        if ( dma_pte_addr(*pte) == 0 )
+        pte_maddr = dma_pte_addr(*pte);
+        if ( !pte_maddr )
         {
             if ( !alloc )
                 break;
 
             pdev = pci_get_pdev_by_domain(domain, -1, -1, -1);
             drhd = acpi_find_matched_drhd_unit(pdev);
-            maddr = alloc_pgtable_maddr(drhd, 1);
-            if ( !maddr )
+            pte_maddr = alloc_pgtable_maddr(drhd, 1);
+            if ( !pte_maddr )
                 break;
 
-            dma_set_pte_addr(*pte, maddr);
-            vaddr = map_vtd_domain_page(maddr);
+            dma_set_pte_addr(*pte, pte_maddr);
 
             /*
              * high level table always sets r/w, last level
@@ -303,21 +302,12 @@ static u64 addr_to_dma_page_maddr(struct domain *domain, u64 addr, int alloc)
             dma_set_pte_writable(*pte);
             iommu_flush_cache_entry(pte, sizeof(struct dma_pte));
         }
-        else
-        {
-            vaddr = map_vtd_domain_page(pte->val);
-        }
 
         if ( level == 2 )
-        {
-            pte_maddr = pte->val & PAGE_MASK_4K;
-            unmap_vtd_domain_page(vaddr);
             break;
-        }
 
         unmap_vtd_domain_page(parent);
-        parent = (struct dma_pte *)vaddr;
-        vaddr = NULL;
+        parent = map_vtd_domain_page(pte_maddr);
         level--;
     }
 
@@ -2449,7 +2439,7 @@ static void vtd_dump_p2m_table_level(paddr_t pt_maddr, int level, paddr_t gpa,
             printk("%*sgfn: %08lx mfn: %08lx\n",
                    indent, "",
                    (unsigned long)(address >> PAGE_SHIFT_4K),
-                   (unsigned long)(pte->val >> PAGE_SHIFT_4K));
+                   (unsigned long)(dma_pte_addr(*pte) >> PAGE_SHIFT_4K));
     }
 
     unmap_vtd_domain_page(pt_vaddr);
diff --git a/xen/drivers/passthrough/vtd/iommu.h b/xen/drivers/passthrough/vtd/iommu.h
index 6b2cf1a..c3e5181 100644
--- a/xen/drivers/passthrough/vtd/iommu.h
+++ b/xen/drivers/passthrough/vtd/iommu.h
@@ -276,7 +276,7 @@ struct dma_pte {
 #define dma_set_pte_snp(p)  do {(p).val |= DMA_PTE_SNP;} while(0)
 #define dma_set_pte_prot(p, prot) \
             do {(p).val = ((p).val & ~3) | ((prot) & 3); } while (0)
-#define dma_pte_addr(p) ((p).val & PAGE_MASK_4K)
+#define dma_pte_addr(p) ((p).val & PADDR_MASK & PAGE_MASK_4K)
 #define dma_set_pte_addr(p, addr) do {\
             (p).val |= ((addr) & PAGE_MASK_4K); } while (0)
 #define dma_pte_present(p) (((p).val & 3) != 0)
diff --git a/xen/drivers/passthrough/vtd/quirks.c b/xen/drivers/passthrough/vtd/quirks.c
index 839dc45..b24fb12 100644
--- a/xen/drivers/passthrough/vtd/quirks.c
+++ b/xen/drivers/passthrough/vtd/quirks.c
@@ -50,6 +50,11 @@
 #define IS_ILK(id)    (id == 0x00408086 || id == 0x00448086 || id== 0x00628086 || id == 0x006A8086)
 #define IS_CPT(id)    (id == 0x01008086 || id == 0x01048086)
 
+/* SandyBridge IGD timeouts in milliseconds */
+#define SNB_IGD_TIMEOUT_LEGACY    1000
+#define SNB_IGD_TIMEOUT            670
+static unsigned int snb_igd_timeout;
+
 static u32 __read_mostly ioh_id;
 static u32 __initdata igd_id;
 bool_t __read_mostly rwbf_quirk;
@@ -158,6 +163,16 @@ static int cantiga_vtd_ops_preamble(struct iommu* iommu)
  * Workaround is to prevent graphics get into RC6
  * state when doing VT-d IOTLB operations, do the VT-d
  * IOTLB operation, and then re-enable RC6 state.
+ *
+ * This quirk is enabled with the snb_igd_quirk command
+ * line parameter.  Specifying snb_igd_quirk with no value
+ * (or any of the standard boolean values) enables this
+ * quirk and sets the timeout to the legacy timeout of
+ * 1000 msec.  Setting this parameter to the string
+ * "cap" enables this quirk and sets the timeout to
+ * the theoretical maximum of 670 msec.  Setting this
+ * parameter to a numerical value enables the quirk and
+ * sets the timeout to that numerical number of msecs.
  */
 static void snb_vtd_ops_preamble(struct iommu* iommu)
 {
@@ -177,7 +192,7 @@ static void snb_vtd_ops_preamble(struct iommu* iommu)
     start_time = NOW();
     while ( (*(volatile u32 *)(igd_reg_va + 0x22AC) & 0xF) != 0 )
     {
-        if ( NOW() > start_time + DMAR_OPERATION_TIMEOUT )
+        if ( NOW() > start_time + snb_igd_timeout )
         {
             dprintk(XENLOG_INFO VTDPREFIX,
                     "snb_vtd_ops_preamble: failed to disable idle handshake\n");
@@ -208,13 +223,10 @@ static void snb_vtd_ops_postamble(struct iommu* iommu)
  * call before VT-d translation enable and IOTLB flush operations.
  */
 
-static int snb_igd_quirk;
-boolean_param("snb_igd_quirk", snb_igd_quirk);
-
 void vtd_ops_preamble_quirk(struct iommu* iommu)
 {
     cantiga_vtd_ops_preamble(iommu);
-    if ( snb_igd_quirk )
+    if ( snb_igd_timeout != 0 )
     {
         spin_lock(&igd_lock);
 
@@ -228,7 +240,7 @@ void vtd_ops_preamble_quirk(struct iommu* iommu)
  */
 void vtd_ops_postamble_quirk(struct iommu* iommu)
 {
-    if ( snb_igd_quirk )
+    if ( snb_igd_timeout != 0 )
     {
         snb_vtd_ops_postamble(iommu);
 
@@ -237,6 +249,28 @@ void vtd_ops_postamble_quirk(struct iommu* iommu)
     }
 }
 
+static void __init parse_snb_timeout(const char *s)
+{
+    int t;
+
+    t = parse_bool(s);
+    if ( t < 0 )
+    {
+        if ( *s == '\0' )
+            t = SNB_IGD_TIMEOUT_LEGACY;
+        else if ( strcmp(s, "cap") == 0 )
+            t = SNB_IGD_TIMEOUT;
+        else
+            t = strtoul(s, NULL, 0);
+    }
+    else
+        t = t ? SNB_IGD_TIMEOUT_LEGACY : 0;
+    snb_igd_timeout = MILLISECS(t);
+
+    return;
+}
+custom_param("snb_igd_quirk", parse_snb_timeout);
+
 /* 5500/5520/X58 Chipset Interrupt remapping errata, for stepping B-3.
  * Fixed in stepping C-2. */
 static void __init tylersburg_intremap_quirk(void)
diff --git a/xen/drivers/passthrough/vtd/utils.c b/xen/drivers/passthrough/vtd/utils.c
index a33564b..db4c326 100644
--- a/xen/drivers/passthrough/vtd/utils.c
+++ b/xen/drivers/passthrough/vtd/utils.c
@@ -170,16 +170,16 @@ void print_vtd_entries(struct iommu *iommu, int bus, int devfn, u64 gmfn)
         l_index = get_level_index(gmfn, level);
         printk("    l%d_index = %x\n", level, l_index);
 
-        pte.val = val = l[l_index];
+        pte.val = l[l_index];
         unmap_vtd_domain_page(l);
-        printk("    l%d[%x] = %"PRIx64"\n", level, l_index, val);
+        printk("    l%d[%x] = %"PRIx64"\n", level, l_index, pte.val);
 
-        pte.val = val;
         if ( !dma_pte_present(pte) )
         {
             printk("    l%d[%x] not present\n", level, l_index);
             break;
         }
+        val = dma_pte_addr(pte);
     } while ( --level );
 }
 
diff --git a/xen/include/asm-arm/arm32/bug.h b/xen/include/asm-arm/arm32/bug.h
index 155b420..3e66f35 100644
--- a/xen/include/asm-arm/arm32/bug.h
+++ b/xen/include/asm-arm/arm32/bug.h
@@ -6,7 +6,7 @@
 /* ARMv7 provides a list of undefined opcode (see A8.8.247 DDI 0406C.b)
  * Use one them encoding A1 to go in exception mode
  */
-#define BUG_OPCODE  0xe7f00f0
+#define BUG_OPCODE  0xe7f000f0
 
 #define BUG_INSTR ".word " __stringify(BUG_OPCODE)
 
diff --git a/xen/include/asm-arm/arm32/spinlock.h b/xen/include/asm-arm/arm32/spinlock.h
index ba11ad6..bc0343c 100644
--- a/xen/include/asm-arm/arm32/spinlock.h
+++ b/xen/include/asm-arm/arm32/spinlock.h
@@ -55,84 +55,6 @@ static always_inline int _raw_spin_trylock(raw_spinlock_t *lock)
     }
 }
 
-typedef struct {
-    volatile unsigned int lock;
-} raw_rwlock_t;
-
-#define _RAW_RW_LOCK_UNLOCKED { 0 }
-
-static always_inline int _raw_read_trylock(raw_rwlock_t *rw)
-{
-    unsigned long tmp, tmp2 = 1;
-
-    __asm__ __volatile__(
-"1: ldrex   %0, [%2]\n"
-"   adds    %0, %0, #1\n"
-"   strexpl %1, %0, [%2]\n"
-    : "=&r" (tmp), "+r" (tmp2)
-    : "r" (&rw->lock)
-    : "cc");
-
-    smp_mb();
-    return tmp2 == 0;
-}
-
-static always_inline int _raw_write_trylock(raw_rwlock_t *rw)
-{
-    unsigned long tmp;
-
-    __asm__ __volatile__(
-"1: ldrex   %0, [%1]\n"
-"   teq     %0, #0\n"
-"   strexeq %0, %2, [%1]"
-    : "=&r" (tmp)
-    : "r" (&rw->lock), "r" (0x80000000)
-    : "cc");
-
-    if (tmp == 0) {
-        smp_mb();
-        return 1;
-    } else {
-        return 0;
-    }
-}
-
-static inline void _raw_read_unlock(raw_rwlock_t *rw)
-{
-    unsigned long tmp, tmp2;
-
-    smp_mb();
-
-    __asm__ __volatile__(
-"1: ldrex   %0, [%2]\n"
-"   sub     %0, %0, #1\n"
-"   strex   %1, %0, [%2]\n"
-"   teq     %1, #0\n"
-"   bne     1b"
-    : "=&r" (tmp), "=&r" (tmp2)
-    : "r" (&rw->lock)
-    : "cc");
-
-    if (tmp == 0)
-        dsb_sev();
-}
-
-static inline void _raw_write_unlock(raw_rwlock_t *rw)
-{
-    smp_mb();
-
-    __asm__ __volatile__(
-    "str    %1, [%0]\n"
-    :
-    : "r" (&rw->lock), "r" (0)
-    : "cc");
-
-    dsb_sev();
-}
-
-#define _raw_rw_is_locked(x) ((x)->lock != 0)
-#define _raw_rw_is_write_locked(x) ((x)->lock == 0x80000000)
-
 #endif /* __ASM_SPINLOCK_H */
 /*
  * Local variables:
diff --git a/xen/include/asm-arm/arm64/spinlock.h b/xen/include/asm-arm/arm64/spinlock.h
index 04300bc..5ae034d 100644
--- a/xen/include/asm-arm/arm64/spinlock.h
+++ b/xen/include/asm-arm/arm64/spinlock.h
@@ -52,69 +52,6 @@ static always_inline int _raw_spin_trylock(raw_spinlock_t *lock)
     return !tmp;
 }
 
-typedef struct {
-    volatile unsigned int lock;
-} raw_rwlock_t;
-
-#define _RAW_RW_LOCK_UNLOCKED { 0 }
-
-static always_inline int _raw_read_trylock(raw_rwlock_t *rw)
-{
-    unsigned int tmp, tmp2 = 1;
-
-    asm volatile(
-        "       ldaxr   %w0, %2\n"
-        "       add     %w0, %w0, #1\n"
-        "       tbnz    %w0, #31, 1f\n"
-        "       stxr    %w1, %w0, %2\n"
-        "1:\n"
-        : "=&r" (tmp), "+r" (tmp2), "+Q" (rw->lock)
-        :
-        : "memory");
-
-    return !tmp2;
-}
-
-static always_inline int _raw_write_trylock(raw_rwlock_t *rw)
-{
-    unsigned int tmp;
-
-    asm volatile(
-        "       ldaxr   %w0, %1\n"
-        "       cbnz    %w0, 1f\n"
-        "       stxr    %w0, %w2, %1\n"
-        "1:\n"
-        : "=&r" (tmp), "+Q" (rw->lock)
-        : "r" (0x80000000)
-        : "memory");
-
-    return !tmp;
-}
-
-static inline void _raw_read_unlock(raw_rwlock_t *rw)
-{
-    unsigned int tmp, tmp2;
-
-    asm volatile(
-        "    1: ldxr    %w0, %2\n"
-        "       sub     %w0, %w0, #1\n"
-        "       stlxr   %w1, %w0, %2\n"
-        "       cbnz    %w1, 1b\n"
-        : "=&r" (tmp), "=&r" (tmp2), "+Q" (rw->lock)
-        :
-        : "memory");
-}
-
-static inline void _raw_write_unlock(raw_rwlock_t *rw)
-{
-    asm volatile(
-        "       stlr    %w1, %0\n"
-        : "=Q" (rw->lock) : "r" (0) : "memory");
-}
-
-#define _raw_rw_is_locked(x) ((x)->lock != 0)
-#define _raw_rw_is_write_locked(x) ((x)->lock == 0x80000000)
-
 #endif /* __ASM_SPINLOCK_H */
 /*
  * Local variables:
diff --git a/xen/include/asm-arm/irq.h b/xen/include/asm-arm/irq.h
index e877334..435dfcd 100644
--- a/xen/include/asm-arm/irq.h
+++ b/xen/include/asm-arm/irq.h
@@ -21,10 +21,10 @@ struct arch_irq_desc {
 
 #define NR_LOCAL_IRQS	32
 #define NR_IRQS		1024
-#define nr_irqs NR_IRQS
 
 #define nr_irqs NR_IRQS
 #define nr_static_irqs NR_IRQS
+#define arch_hwdom_irqs(domid) NR_IRQS
 
 struct irq_desc;
 struct irqaction;
diff --git a/xen/include/asm-x86/setup.h b/xen/include/asm-x86/setup.h
index 8f8c6f3..762eb02 100644
--- a/xen/include/asm-x86/setup.h
+++ b/xen/include/asm-x86/setup.h
@@ -35,6 +35,8 @@ int construct_dom0(
 unsigned long initial_images_nrpages(void);
 void discard_initial_images(void);
 
+unsigned int dom0_max_vcpus(void);
+
 int xen_in_range(unsigned long mfn);
 
 void microcode_grab_module(
diff --git a/xen/include/asm-x86/softirq.h b/xen/include/asm-x86/softirq.h
index ec787d6..7225dea 100644
--- a/xen/include/asm-x86/softirq.h
+++ b/xen/include/asm-x86/softirq.h
@@ -7,8 +7,7 @@
 
 #define MACHINE_CHECK_SOFTIRQ  (NR_COMMON_SOFTIRQS + 3)
 #define PCI_SERR_SOFTIRQ       (NR_COMMON_SOFTIRQS + 4)
-#define HVM_DPCI_SOFTIRQ       (NR_COMMON_SOFTIRQS + 5)
-#define NR_ARCH_SOFTIRQS       6
+#define NR_ARCH_SOFTIRQS       5
 
 bool_t arch_skip_send_event_check(unsigned int cpu);
 
diff --git a/xen/include/asm-x86/spinlock.h b/xen/include/asm-x86/spinlock.h
index 6bc044c..06d9b04 100644
--- a/xen/include/asm-x86/spinlock.h
+++ b/xen/include/asm-x86/spinlock.h
@@ -31,58 +31,4 @@ static always_inline int _raw_spin_trylock(raw_spinlock_t *lock)
     return (oldval > 0);
 }
 
-typedef struct {
-    volatile int lock;
-} raw_rwlock_t;
-
-#define RW_WRITE_BIAS 0x7fffffff
-#define _RAW_RW_LOCK_UNLOCKED /*(raw_rwlock_t)*/ { 0 }
-
-static always_inline int _raw_read_trylock(raw_rwlock_t *rw)
-{
-    int acquired;
-
-    asm volatile (
-        "    lock; decl %0         \n"
-        "    jns 2f                \n"
-#ifdef __clang__ /* clang's builtin assember can't do .subsection */
-        "1:  .pushsection .fixup,\"ax\"\n"
-#else
-        "1:  .subsection 1         \n"
-#endif
-        "2:  lock; incl %0         \n"
-        "    decl %1               \n"
-        "    jmp 1b                \n"
-#ifdef __clang__
-        "    .popsection           \n"
-#else
-        "    .subsection 0         \n"
-#endif
-        : "=m" (rw->lock), "=r" (acquired) : "1" (1) : "memory" );
-
-    return acquired;
-}
-
-static always_inline int _raw_write_trylock(raw_rwlock_t *rw)
-{
-    return (cmpxchg(&rw->lock, 0, RW_WRITE_BIAS) == 0);
-}
-
-static always_inline void _raw_read_unlock(raw_rwlock_t *rw)
-{
-    asm volatile (
-        "lock ; incl %0"
-        : "=m" ((rw)->lock) : : "memory" );
-}
-
-static always_inline void _raw_write_unlock(raw_rwlock_t *rw)
-{
-    asm volatile (
-        "lock ; subl %1,%0"
-        : "=m" ((rw)->lock) : "i" (RW_WRITE_BIAS) : "memory" );
-}
-
-#define _raw_rw_is_locked(x) ((x)->lock != 0)
-#define _raw_rw_is_write_locked(x) ((x)->lock > 0)
-
 #endif /* __ASM_SPINLOCK_H */
diff --git a/xen/include/xen/8250-uart.h b/xen/include/xen/8250-uart.h
index a682bae..304b9dd 100644
--- a/xen/include/xen/8250-uart.h
+++ b/xen/include/xen/8250-uart.h
@@ -32,6 +32,7 @@
 #define UART_MCR          0x04    /* Modem control        */
 #define UART_LSR          0x05    /* line status          */
 #define UART_MSR          0x06    /* Modem status         */
+#define UART_SYSC         0x15    /* System configuration register */
 #define UART_USR          0x1f    /* Status register (DW) */
 #define UART_DLL          0x00    /* divisor latch (ls) (DLAB=1) */
 #define UART_DLM          0x01    /* divisor latch (ms) (DLAB=1) */
@@ -145,6 +146,9 @@
 /* SCR register bitmasks */
 #define OMAP_UART_SCR_RX_TRIG_GRANU1_MASK (1 << 7)
 
+/* System configuration register */
+#define OMAP_UART_SYSC_DEF_CONF 0x0d /* autoidle mode, wakeup is enabled */
+
 #endif /* __XEN_8250_UART_H__ */
 
 /*
diff --git a/xen/include/xen/console.h b/xen/include/xen/console.h
index cfb07a2..c7fd9ca 100644
--- a/xen/include/xen/console.h
+++ b/xen/include/xen/console.h
@@ -14,6 +14,7 @@ struct xen_sysctl_readconsole;
 long read_console_ring(struct xen_sysctl_readconsole *op);
 
 void console_init_preirq(void);
+void console_init_ring(void);
 void console_init_postirq(void);
 void console_endboot(void);
 int console_has(const char *device);
diff --git a/xen/include/xen/hvm/irq.h b/xen/include/xen/hvm/irq.h
index 3996f1f..c89f4b1 100644
--- a/xen/include/xen/hvm/irq.h
+++ b/xen/include/xen/hvm/irq.h
@@ -88,19 +88,18 @@ struct hvm_irq_dpci {
     DECLARE_BITMAP(isairq_map, NR_ISAIRQS);
     /* Record of mapped Links */
     uint8_t link_cnt[NR_LINK];
+    struct tasklet dirq_tasklet;
 };
 
 /* Machine IRQ to guest device/intx mapping. */
 struct hvm_pirq_dpci {
     uint32_t flags;
-    unsigned int state;
     bool_t masked;
     uint16_t pending;
     struct list_head digl_list;
     struct domain *dom;
     struct hvm_gmsi_info gmsi;
     struct timer timer;
-    struct list_head softirq_list;
 };
 
 void pt_pirq_init(struct domain *, struct hvm_pirq_dpci *);
@@ -110,7 +109,6 @@ int pt_pirq_iterate(struct domain *d,
                               struct hvm_pirq_dpci *, void *arg),
                     void *arg);
 
-bool_t pt_pirq_softirq_active(struct hvm_pirq_dpci *);
 /* Modify state of a PCI INTx wire. */
 void hvm_pci_intx_assert(
     struct domain *d, unsigned int device, unsigned int intx);
diff --git a/xen/include/xen/hypercall.h b/xen/include/xen/hypercall.h
index a9e5229..8c55779 100644
--- a/xen/include/xen/hypercall.h
+++ b/xen/include/xen/hypercall.h
@@ -57,6 +57,11 @@ do_platform_op(
  * To allow safe resume of do_memory_op() after preemption, we need to know
  * at what point in the page list to resume. For this purpose I steal the
  * high-order bits of the @cmd parameter, which are otherwise unused and zero.
+ *
+ * Note that both of these values are effectively part of the ABI, even if
+ * we don't need to make them a formal part of it: A guest suspended for
+ * migration in the middle of a continuation would fail to work if resumed on
+ * a hypervisor using different values.
  */
 #define MEMOP_EXTENT_SHIFT 6 /* cmd[:6] == start_extent */
 #define MEMOP_CMD_MASK     ((1 << MEMOP_EXTENT_SHIFT) - 1)
diff --git a/xen/include/xen/iocap.h b/xen/include/xen/iocap.h
index b755ecb..1ca3858 100644
--- a/xen/include/xen/iocap.h
+++ b/xen/include/xen/iocap.h
@@ -28,22 +28,11 @@
 #define irq_access_permitted(d, i)                      \
     rangeset_contains_singleton((d)->irq_caps, i)
 
-#define pirq_permit_access(d, i) ({                     \
-    struct domain *d__ = (d);                           \
-    int i__ = domain_pirq_to_irq(d__, i);               \
-    i__ > 0 ? rangeset_add_singleton(d__->irq_caps, i__)\
-            : -EINVAL;                                  \
-})
-#define pirq_deny_access(d, i) ({                       \
-    struct domain *d__ = (d);                           \
-    int i__ = domain_pirq_to_irq(d__, i);               \
-    i__ > 0 ? rangeset_remove_singleton(d__->irq_caps, i__)\
-            : -EINVAL;                                  \
-})
 #define pirq_access_permitted(d, i) ({                  \
     struct domain *d__ = (d);                           \
-    rangeset_contains_singleton(d__->irq_caps,          \
-                                domain_pirq_to_irq(d__, i));\
+    int irq__ = domain_pirq_to_irq(d__, i);             \
+    irq__ > 0 && irq_access_permitted(d__, irq__)       \
+    ? irq__ : 0;                                        \
 })
 
 #endif /* __XEN_IOCAP_H__ */
diff --git a/xen/include/xen/irq.h b/xen/include/xen/irq.h
index ffb5932..9e0155c 100644
--- a/xen/include/xen/irq.h
+++ b/xen/include/xen/irq.h
@@ -168,4 +168,8 @@ static inline void set_native_irq_info(unsigned int irq, const cpumask_t *mask)
 
 unsigned int set_desc_affinity(struct irq_desc *, const cpumask_t *);
 
+#ifndef arch_hwdom_irqs
+unsigned int arch_hwdom_irqs(domid_t);
+#endif
+
 #endif /* __XEN_IRQ_H__ */
diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
index 5f295f3..91520bc 100644
--- a/xen/include/xen/pci.h
+++ b/xen/include/xen/pci.h
@@ -99,7 +99,7 @@ struct pci_dev *pci_lock_domain_pdev(
 
 void setup_hwdom_pci_devices(struct domain *,
                             int (*)(u8 devfn, struct pci_dev *));
-int pci_release_devices(struct domain *d);
+void pci_release_devices(struct domain *d);
 int pci_add_segment(u16 seg);
 const unsigned long *pci_get_ro_map(u16 seg);
 int pci_add_device(u16 seg, u8 bus, u8 devfn, const struct pci_dev_info *);
diff --git a/xen/include/xen/spinlock.h b/xen/include/xen/spinlock.h
index 12b0a89..eda9b2e 100644
--- a/xen/include/xen/spinlock.h
+++ b/xen/include/xen/spinlock.h
@@ -141,11 +141,13 @@ typedef struct spinlock {
 #define spin_lock_init(l) (*(l) = (spinlock_t)SPIN_LOCK_UNLOCKED)
 
 typedef struct {
-    raw_rwlock_t raw;
+    volatile uint32_t lock;
     struct lock_debug debug;
 } rwlock_t;
 
-#define RW_LOCK_UNLOCKED { _RAW_RW_LOCK_UNLOCKED, _LOCK_DEBUG }
+#define RW_WRITE_FLAG (1u<<31)
+
+#define RW_LOCK_UNLOCKED { 0, _LOCK_DEBUG }
 #define DEFINE_RWLOCK(l) rwlock_t l = RW_LOCK_UNLOCKED
 #define rwlock_init(l) (*(l) = (rwlock_t)RW_LOCK_UNLOCKED)
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-xen/xen.git



More information about the Pkg-xen-changes mailing list