WARNING - OLD ARCHIVES

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

xen-changelog

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

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 16 Jun 2006 18:41:02 +0000
Delivery-date: Fri, 16 Jun 2006 11:46:45 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID e74c47d073ee9f9392540576e53508f9c5b16a65
# Parent  b8f6089cbce30c79809d5e00888b92007f3a9153
# Parent  912588576817fddae490a9bea71c58d2f8ea9802
merge with xen-unstable.hg
---
 linux-2.6-xen-sparse/arch/ia64/xen/drivers/Makefile                     |   21 
 linux-2.6-xen-sparse/arch/ia64/xen/drivers/README                       |    2 
 linux-2.6-xen-sparse/arch/ia64/xen/drivers/coreMakefile                 |   19 
 linux-2.6-xen-sparse/drivers/xen/blktap/Makefile                        |    3 
 linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c                        |  900 
----------
 linux-2.6-xen-sparse/drivers/xen/blktap/common.h                        |  100 
-
 linux-2.6-xen-sparse/drivers/xen/blktap/interface.c                     |  134 
-
 linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c                        |  223 
--
 buildconfigs/linux-defconfig_xen0_ia64                                  |    2 
 buildconfigs/linux-defconfig_xen0_x86_32                                |    2 
 buildconfigs/linux-defconfig_xen0_x86_64                                |    2 
 buildconfigs/linux-defconfig_xen_ia64                                   |    2 
 buildconfigs/linux-defconfig_xen_x86_32                                 |    2 
 buildconfigs/linux-defconfig_xen_x86_64                                 |    2 
 linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S                        |    2 
 linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c                       |   16 
 linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c                         |   35 
 linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c                        |   11 
 linux-2.6-xen-sparse/arch/i386/kernel/vm86.c                            |    4 
 linux-2.6-xen-sparse/arch/i386/mm/init-xen.c                            |   14 
 linux-2.6-xen-sparse/arch/ia64/Kconfig                                  |   36 
 linux-2.6-xen-sparse/arch/ia64/xen-mkbuildtree-pre                      |    5 
 linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c                      |    6 
 linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c                    |   58 
 linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c                     |   32 
 linux-2.6-xen-sparse/arch/x86_64/kernel/smp-xen.c                       |    2 
 linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c                          |   50 
 linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c                         |   16 
 linux-2.6-xen-sparse/drivers/xen/Kconfig                                |   53 
 linux-2.6-xen-sparse/drivers/xen/Makefile                               |   10 
 linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c                      |   22 
 linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c                      |   18 
 linux-2.6-xen-sparse/drivers/xen/blkback/common.h                       |    9 
 linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c                       |   20 
 linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c                    |   43 
 linux-2.6-xen-sparse/drivers/xen/blkfront/block.h                       |   11 
 linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c                         |    1 
 linux-2.6-xen-sparse/drivers/xen/char/mem.c                             |    8 
 linux-2.6-xen-sparse/drivers/xen/console/console.c                      |    2 
 linux-2.6-xen-sparse/drivers/xen/core/Makefile                          |   16 
 linux-2.6-xen-sparse/drivers/xen/core/cpu_hotplug.c                     |    2 
 linux-2.6-xen-sparse/drivers/xen/core/evtchn.c                          |   63 
 linux-2.6-xen-sparse/drivers/xen/core/gnttab.c                          |  202 
--
 linux-2.6-xen-sparse/drivers/xen/core/reboot.c                          |    8 
 linux-2.6-xen-sparse/drivers/xen/core/smpboot.c                         |    9 
 linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c                        |    6 
 linux-2.6-xen-sparse/drivers/xen/netback/common.h                       |   13 
 linux-2.6-xen-sparse/drivers/xen/netback/interface.c                    |    2 
 linux-2.6-xen-sparse/drivers/xen/netback/loopback.c                     |    2 
 linux-2.6-xen-sparse/drivers/xen/netback/netback.c                      |  324 
++-
 linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c                       |   46 
 linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c                    |  263 
+-
 linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c                       |   22 
 linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c                      |   16 
 linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c                      |   18 
 linux-2.6-xen-sparse/drivers/xen/tpmback/common.h                       |   16 
 linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c                       |   56 
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c                 |    8 
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c                    |    6 
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c                  |   53 
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c                     |   36 
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hw_irq.h             |    6 
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h          |    2 
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h             |    6 
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h        |    7 
 linux-2.6-xen-sparse/include/asm-ia64/hw_irq.h                          |   11 
 linux-2.6-xen-sparse/include/asm-ia64/page.h                            |   10 
 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hw_irq.h           |    6 
 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h        |    2 
 linux-2.6-xen-sparse/include/linux/interrupt.h                          |  301 
+++
 linux-2.6-xen-sparse/include/xen/public/privcmd.h                       |   16 
 linux-2.6-xen-sparse/include/xen/xenbus.h                               |   35 
 linux-2.6-xen-sparse/kernel/irq/spurious.c                              |  206 
++
 linux-2.6-xen-sparse/mm/memory.c                                        |    2 
 patches/linux-2.6.16.13/rcu_needs_cpu.patch                             |   16 
 tools/debugger/libxendebug/xendebug.c                                   |    7 
 tools/examples/network-bridge                                           |    1 
 tools/firmware/hvmloader/Makefile                                       |    4 
 tools/firmware/rombios/Makefile                                         |    4 
 tools/firmware/vgabios/clext.c                                          |   46 
 tools/firmware/vmxassist/vm86.c                                         |   65 
 tools/ioemu/hw/cirrus_vga.c                                             |   28 
 tools/ioemu/hw/pc.c                                                     |   11 
 tools/ioemu/hw/pckbd.c                                                  |  183 
--
 tools/ioemu/hw/usb-hid.c                                                |  537 
+++++
 tools/ioemu/hw/usb-hub.c                                                |  549 
++++++
 tools/ioemu/hw/usb-uhci.c                                               |  680 
+++++++
 tools/ioemu/hw/usb.c                                                    |  193 
++
 tools/ioemu/hw/usb.h                                                    |  166 
+
 tools/ioemu/hw/vga.c                                                    |    2 
 tools/ioemu/monitor.c                                                   |    8 
 tools/ioemu/sdl.c                                                       |   46 
 tools/ioemu/target-i386-dm/Makefile                                     |    3 
 tools/ioemu/usb-linux.c                                                 |  488 
+++++
 tools/ioemu/vl.c                                                        |  203 
++
 tools/ioemu/vl.h                                                        |   23 
 tools/ioemu/vnc.c                                                       |   58 
 tools/libxc/xc_core.c                                                   |   12 
 tools/libxc/xc_domain.c                                                 |   18 
 tools/libxc/xc_hvm_build.c                                              |   10 
 tools/libxc/xc_ia64_stubs.c                                             |   14 
 tools/libxc/xc_linux.c                                                  |    2 
 tools/libxc/xc_linux_build.c                                            |  171 
+
 tools/libxc/xc_linux_restore.c                                          |  216 
++
 tools/libxc/xc_linux_save.c                                             |   69 
 tools/libxc/xc_load_aout9.c                                             |    4 
 tools/libxc/xc_load_bin.c                                               |    4 
 tools/libxc/xc_load_elf.c                                               |   19 
 tools/libxc/xc_pagetab.c                                                |   22 
 tools/libxc/xc_private.c                                                |   68 
 tools/libxc/xc_private.h                                                |   51 
 tools/libxc/xc_ptrace.c                                                 |   29 
 tools/libxc/xc_ptrace.h                                                 |    1 
 tools/libxc/xc_ptrace_core.c                                            |   23 
 tools/libxc/xenctrl.h                                                   |   19 
 tools/libxc/xg_private.h                                                |   25 
 tools/libxc/xg_save_restore.h                                           |   34 
 tools/python/xen/lowlevel/acm/acm.c                                     |   14 
 tools/python/xen/lowlevel/xs/xs.c                                       |   68 
 tools/python/xen/util/security.py                                       |    9 
 tools/python/xen/xend/image.py                                          |    5 
 tools/python/xen/xm/create.py                                           |   23 
 tools/tests/test_x86_emulator.c                                         |  131 
-
 tools/xm-test/configure.ac                                              |    3 
 tools/xm-test/grouptest/default                                         |    1 
 tools/xm-test/ramdisk/Makefile.am                                       |    2 
 tools/xm-test/ramdisk/README-XenSource-initrd-0.8-img                   |   42 
 tools/xm-test/ramdisk/configs/busybox                                   |    4 
 tools/xm-test/tests/Makefile.am                                         |    1 
 tools/xm-test/tests/block-integrity/02_block_device_write_verify.py     |   63 
 tools/xm-test/tests/block-integrity/Makefile.am                         |    3 
 tools/xm-test/tests/enforce_dom0_cpus/01_enforce_dom0_cpus_basic_pos.py |   21 
 tools/xm-test/tests/sched-credit/01_sched_credit_weight_cap_pos.py      |   65 
 tools/xm-test/tests/sched-credit/Makefile.am                            |   20 
 xen/acm/acm_core.c                                                      |    2 
 xen/acm/acm_policy.c                                                    |   23 
 xen/acm/acm_simple_type_enforcement_hooks.c                             |   14 
 xen/arch/ia64/linux-xen/smpboot.c                                       |    3 
 xen/arch/ia64/vmx/vmx_init.c                                            |    3 
 xen/arch/ia64/xen/domain.c                                              |    1 
 xen/arch/ia64/xen/xensetup.c                                            |    2 
 xen/arch/x86/audit.c                                                    |    4 
 xen/arch/x86/cpu/mtrr/main.c                                            |    2 
 xen/arch/x86/dom0_ops.c                                                 |    2 
 xen/arch/x86/domain.c                                                   |   48 
 xen/arch/x86/domain_build.c                                             |    9 
 xen/arch/x86/hvm/intercept.c                                            |   14 
 xen/arch/x86/hvm/io.c                                                   |    7 
 xen/arch/x86/hvm/platform.c                                             |   94 
-
 xen/arch/x86/hvm/svm/svm.c                                              |   80 
 xen/arch/x86/hvm/vmx/vmcs.c                                             |  177 
+
 xen/arch/x86/hvm/vmx/vmx.c                                              |  220 
+-
 xen/arch/x86/hvm/vmx/x86_32/exits.S                                     |  109 
-
 xen/arch/x86/hvm/vmx/x86_64/exits.S                                     |  146 
-
 xen/arch/x86/i8259.c                                                    |    2 
 xen/arch/x86/irq.c                                                      |   22 
 xen/arch/x86/microcode.c                                                |    2 
 xen/arch/x86/mm.c                                                       |  137 
-
 xen/arch/x86/physdev.c                                                  |    9 
 xen/arch/x86/setup.c                                                    |    2 
 xen/arch/x86/shadow.c                                                   |    9 
 xen/arch/x86/shadow32.c                                                 |   14 
 xen/arch/x86/shadow_public.c                                            |   14 
 xen/arch/x86/smp.c                                                      |    2 
 xen/arch/x86/smpboot.c                                                  |   17 
 xen/arch/x86/time.c                                                     |    6 
 xen/arch/x86/traps.c                                                    |   13 
 xen/arch/x86/x86_32/asm-offsets.c                                       |    5 
 xen/arch/x86/x86_32/domain_page.c                                       |    2 
 xen/arch/x86/x86_32/entry.S                                             |   12 
 xen/arch/x86/x86_32/mm.c                                                |    3 
 xen/arch/x86/x86_32/traps.c                                             |    8 
 xen/arch/x86/x86_64/asm-offsets.c                                       |    6 
 xen/arch/x86/x86_64/entry.S                                             |   20 
 xen/arch/x86/x86_64/mm.c                                                |    3 
 xen/arch/x86/x86_64/traps.c                                             |   14 
 xen/arch/x86/x86_emulate.c                                              |   19 
 xen/common/acm_ops.c                                                    |   12 
 xen/common/dom0_ops.c                                                   |    2 
 xen/common/domain.c                                                     |  134 
+
 xen/common/event_channel.c                                              |   23 
 xen/common/kernel.c                                                     |    5 
 xen/common/keyhandler.c                                                 |    5 
 xen/common/memory.c                                                     |   20 
 xen/common/page_alloc.c                                                 |    4 
 xen/common/perfc.c                                                      |    2 
 xen/common/sched_bvt.c                                                  |   36 
 xen/common/sched_credit.c                                               |   30 
 xen/common/sched_sedf.c                                                 |   39 
 xen/common/schedule.c                                                   |  129 
-
 xen/common/trace.c                                                      |   12 
 xen/common/xmalloc.c                                                    |    2 
 xen/drivers/char/console.c                                              |   13 
 xen/include/acm/acm_core.h                                              |   13 
 xen/include/asm-ia64/config.h                                           |    5 
 xen/include/asm-ia64/event.h                                            |   20 
 xen/include/asm-ia64/vmx_vcpu.h                                         |    2 
 xen/include/asm-ia64/vmx_vpd.h                                          |    3 
 xen/include/asm-ia64/xenpage.h                                          |    4 
 xen/include/asm-x86/config.h                                            |    5 
 xen/include/asm-x86/event.h                                             |   26 
 xen/include/asm-x86/hvm/io.h                                            |    7 
 xen/include/asm-x86/hvm/vmx/cpu.h                                       |   17 
 xen/include/asm-x86/hvm/vmx/vmcs.h                                      |   56 
 xen/include/asm-x86/hvm/vmx/vmx.h                                       |   84 
 xen/include/asm-x86/irq.h                                               |    3 
 xen/include/asm-x86/multicall.h                                         |   79 
 xen/include/asm-x86/page.h                                              |   11 
 xen/include/asm-x86/shadow.h                                            |   37 
 xen/include/public/acm.h                                                |    3 
 xen/include/public/acm_ops.h                                            |   23 
 xen/include/public/arch-ia64.h                                          |    3 
 xen/include/public/arch-x86_32.h                                        |   27 
 xen/include/public/arch-x86_64.h                                        |   24 
 xen/include/public/callback.h                                           |   15 
 xen/include/public/dom0_ops.h                                           |   56 
 xen/include/public/grant_table.h                                        |    2 
 xen/include/public/io/netif.h                                           |    4 
 xen/include/public/io/ring.h                                            |   16 
 xen/include/public/memory.h                                             |   10 
 xen/include/public/physdev.h                                            |    7 
 xen/include/public/xen.h                                                |   22 
 xen/include/xen/console.h                                               |    2 
 xen/include/xen/domain.h                                                |   23 
 xen/include/xen/event.h                                                 |    3 
 xen/include/xen/mm.h                                                    |    7 
 xen/include/xen/sched-if.h                                              |   11 
 xen/include/xen/sched.h                                                 |   22 
 228 files changed, 6942 insertions(+), 3781 deletions(-)

diff -r b8f6089cbce3 -r e74c47d073ee buildconfigs/linux-defconfig_xen0_ia64
--- a/buildconfigs/linux-defconfig_xen0_ia64    Tue Jun 13 09:00:32 2006 -0600
+++ b/buildconfigs/linux-defconfig_xen0_ia64    Tue Jun 13 12:12:24 2006 -0600
@@ -1529,14 +1529,12 @@ CONFIG_XEN_BACKEND=y
 CONFIG_XEN_BACKEND=y
 # CONFIG_XEN_PCIDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_BACKEND=y
-# CONFIG_XEN_BLKDEV_TAP_BE is not set
 CONFIG_XEN_NETDEV_BACKEND=y
 # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
 CONFIG_XEN_NETDEV_LOOPBACK=y
 # CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
-# CONFIG_XEN_BLKDEV_TAP is not set
 # CONFIG_XEN_SCRUB_PAGES is not set
 # CONFIG_XEN_DISABLE_SERIAL is not set
 CONFIG_XEN_SYSFS=y
diff -r b8f6089cbce3 -r e74c47d073ee buildconfigs/linux-defconfig_xen0_x86_32
--- a/buildconfigs/linux-defconfig_xen0_x86_32  Tue Jun 13 09:00:32 2006 -0600
+++ b/buildconfigs/linux-defconfig_xen0_x86_32  Tue Jun 13 12:12:24 2006 -0600
@@ -1322,14 +1322,12 @@ CONFIG_XEN_PCIDEV_BACKEND_PASS=y
 CONFIG_XEN_PCIDEV_BACKEND_PASS=y
 # CONFIG_XEN_PCIDEV_BE_DEBUG is not set
 CONFIG_XEN_BLKDEV_BACKEND=y
-# CONFIG_XEN_BLKDEV_TAP_BE is not set
 CONFIG_XEN_NETDEV_BACKEND=y
 # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
 CONFIG_XEN_NETDEV_LOOPBACK=y
 # CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
-# CONFIG_XEN_BLKDEV_TAP is not set
 CONFIG_XEN_SCRUB_PAGES=y
 CONFIG_XEN_DISABLE_SERIAL=y
 CONFIG_XEN_SYSFS=y
diff -r b8f6089cbce3 -r e74c47d073ee buildconfigs/linux-defconfig_xen0_x86_64
--- a/buildconfigs/linux-defconfig_xen0_x86_64  Tue Jun 13 09:00:32 2006 -0600
+++ b/buildconfigs/linux-defconfig_xen0_x86_64  Tue Jun 13 12:12:24 2006 -0600
@@ -1263,14 +1263,12 @@ CONFIG_XEN_PCIDEV_BACKEND_PASS=y
 CONFIG_XEN_PCIDEV_BACKEND_PASS=y
 # CONFIG_XEN_PCIDEV_BE_DEBUG is not set
 CONFIG_XEN_BLKDEV_BACKEND=y
-# CONFIG_XEN_BLKDEV_TAP_BE is not set
 CONFIG_XEN_NETDEV_BACKEND=y
 # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
 CONFIG_XEN_NETDEV_LOOPBACK=y
 # CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
-# CONFIG_XEN_BLKDEV_TAP is not set
 CONFIG_XEN_SCRUB_PAGES=y
 CONFIG_XEN_DISABLE_SERIAL=y
 CONFIG_XEN_SYSFS=y
diff -r b8f6089cbce3 -r e74c47d073ee buildconfigs/linux-defconfig_xen_ia64
--- a/buildconfigs/linux-defconfig_xen_ia64     Tue Jun 13 09:00:32 2006 -0600
+++ b/buildconfigs/linux-defconfig_xen_ia64     Tue Jun 13 12:12:24 2006 -0600
@@ -1535,14 +1535,12 @@ CONFIG_XEN_BACKEND=y
 CONFIG_XEN_BACKEND=y
 # CONFIG_XEN_PCIDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_BACKEND=y
-# CONFIG_XEN_BLKDEV_TAP_BE is not set
 CONFIG_XEN_NETDEV_BACKEND=y
 # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
 CONFIG_XEN_NETDEV_LOOPBACK=y
 # CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
-# CONFIG_XEN_BLKDEV_TAP is not set
 # CONFIG_XEN_SCRUB_PAGES is not set
 # CONFIG_XEN_DISABLE_SERIAL is not set
 CONFIG_XEN_SYSFS=y
diff -r b8f6089cbce3 -r e74c47d073ee buildconfigs/linux-defconfig_xen_x86_32
--- a/buildconfigs/linux-defconfig_xen_x86_32   Tue Jun 13 09:00:32 2006 -0600
+++ b/buildconfigs/linux-defconfig_xen_x86_32   Tue Jun 13 12:12:24 2006 -0600
@@ -3022,14 +3022,12 @@ CONFIG_XEN_PCIDEV_BACKEND_VPCI=y
 # CONFIG_XEN_PCIDEV_BACKEND_PASS is not set
 # CONFIG_XEN_PCIDEV_BE_DEBUG is not set
 CONFIG_XEN_BLKDEV_BACKEND=y
-# CONFIG_XEN_BLKDEV_TAP_BE is not set
 CONFIG_XEN_NETDEV_BACKEND=y
 # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
 CONFIG_XEN_NETDEV_LOOPBACK=y
 # CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
-# CONFIG_XEN_BLKDEV_TAP is not set
 CONFIG_XEN_SCRUB_PAGES=y
 CONFIG_XEN_DISABLE_SERIAL=y
 CONFIG_XEN_SYSFS=y
diff -r b8f6089cbce3 -r e74c47d073ee buildconfigs/linux-defconfig_xen_x86_64
--- a/buildconfigs/linux-defconfig_xen_x86_64   Tue Jun 13 09:00:32 2006 -0600
+++ b/buildconfigs/linux-defconfig_xen_x86_64   Tue Jun 13 12:12:24 2006 -0600
@@ -2854,7 +2854,6 @@ CONFIG_XEN_PCIDEV_BACKEND_PASS=y
 CONFIG_XEN_PCIDEV_BACKEND_PASS=y
 # CONFIG_XEN_PCIDEV_BE_DEBUG is not set
 CONFIG_XEN_BLKDEV_BACKEND=y
-# CONFIG_XEN_BLKDEV_TAP_BE is not set
 CONFIG_XEN_NETDEV_BACKEND=y
 # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
 CONFIG_XEN_NETDEV_LOOPBACK=y
@@ -2862,7 +2861,6 @@ CONFIG_XEN_TPMDEV_BACKEND=m
 # CONFIG_XEN_TPMDEV_CLOSE_IF_VTPM_FAILS is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
-# CONFIG_XEN_BLKDEV_TAP is not set
 CONFIG_XEN_SCRUB_PAGES=y
 CONFIG_XEN_DISABLE_SERIAL=y
 CONFIG_XEN_SYSFS=y
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S
--- a/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S  Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S  Tue Jun 13 12:12:24 
2006 -0600
@@ -173,7 +173,7 @@ ENTRY(cpu_gdt_table)
        .ascii           "|pae_pgdir_above_4gb"
        .ascii           "|supervisor_mode_kernel"
 #ifdef CONFIG_X86_PAE
-       .ascii  ",PAE=yes"
+       .ascii  ",PAE=yes[extended-cr3]"
 #else
        .ascii  ",PAE=no"
 #endif
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Tue Jun 13 12:12:24 
2006 -0600
@@ -1378,7 +1378,6 @@ legacy_init_iomem_resources(struct e820e
                res->end = res->start + e820[i].size - 1;
                res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
                request_resource(&iomem_resource, res);
-#ifndef CONFIG_XEN
                if (e820[i].type == E820_RAM) {
                        /*
                         *  We don't know which RAM region contains kernel data,
@@ -1391,7 +1390,6 @@ legacy_init_iomem_resources(struct e820e
                        request_resource(res, &crashk_res);
 #endif
                }
-#endif
        }
 }
 
@@ -1460,8 +1458,11 @@ static void __init register_memory(void)
        int           i;
 
        /* Nothing to do if not running in dom0. */
-       if (!(xen_start_info->flags & SIF_INITDOMAIN))
+       if (!(xen_start_info->flags & SIF_INITDOMAIN)) {
+               legacy_init_iomem_resources(e820.map, e820.nr_map,
+                                           &code_resource, &data_resource);
                return;
+       }
 
 #ifdef CONFIG_XEN
        machine_e820 = alloc_bootmem_low_pages(PAGE_SIZE);
@@ -1698,11 +1699,10 @@ void __init setup_arch(char **cmdline_p)
        init_mm.brk = (PFN_UP(__pa(xen_start_info->pt_base)) +
                       xen_start_info->nr_pt_frames) << PAGE_SHIFT;
 
-       /* XEN: This is nonsense: kernel may not even be contiguous in RAM. */
-       /*code_resource.start = virt_to_phys(_text);*/
-       /*code_resource.end = virt_to_phys(_etext)-1;*/
-       /*data_resource.start = virt_to_phys(_etext);*/
-       /*data_resource.end = virt_to_phys(_edata)-1;*/
+       code_resource.start = virt_to_phys(_text);
+       code_resource.end = virt_to_phys(_etext)-1;
+       data_resource.start = virt_to_phys(_etext);
+       data_resource.end = virt_to_phys(_edata)-1;
 
        parse_cmdline_early(cmdline_p);
 
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c   Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c   Tue Jun 13 12:12:24 
2006 -0600
@@ -47,6 +47,9 @@ EXPORT_SYMBOL(swiotlb);
  */
 #define IO_TLB_SHIFT 11
 
+/* Width of DMA addresses in the IO TLB. 31 bits is an aacraid limitation. */
+#define IO_TLB_DMA_BITS 31
+
 static int swiotlb_force;
 static char *iotlb_virt_start;
 static unsigned long iotlb_nslabs;
@@ -56,10 +59,16 @@ static unsigned long iotlb_nslabs;
  * swiotlb_sync_single_*, to see if the memory was in fact allocated by this
  * API.
  */
-static dma_addr_t iotlb_bus_start, iotlb_bus_end, iotlb_bus_mask;
+static unsigned long iotlb_pfn_start, iotlb_pfn_end;
 
 /* Does the given dma address reside within the swiotlb aperture? */
-#define in_swiotlb_aperture(a) (!(((a) ^ iotlb_bus_start) & iotlb_bus_mask))
+static inline int in_swiotlb_aperture(dma_addr_t dev_addr)
+{
+       unsigned long pfn = mfn_to_local_pfn(dev_addr >> PAGE_SHIFT);
+       return (pfn_valid(pfn)
+               && (pfn >= iotlb_pfn_start)
+               && (pfn < iotlb_pfn_end));
+}
 
 /*
  * When the IOMMU overflows we return a fallback buffer. This sets the size.
@@ -125,7 +134,6 @@ swiotlb_init_with_default_size (size_t d
 swiotlb_init_with_default_size (size_t default_size)
 {
        unsigned long i, bytes;
-       int rc;
 
        if (!iotlb_nslabs) {
                iotlb_nslabs = (default_size >> IO_TLB_SHIFT);
@@ -146,10 +154,13 @@ swiotlb_init_with_default_size (size_t d
                      "Use dom0_mem Xen boot parameter to reserve\n"
                      "some DMA memory (e.g., dom0_mem=-128M).\n");
 
-       /* Hardcode 31 address bits for now: aacraid limitation. */
-       rc = xen_create_contiguous_region(
-               (unsigned long)iotlb_virt_start, get_order(bytes), 31);
-       BUG_ON(rc);
+       for (i = 0; i < iotlb_nslabs; i += IO_TLB_SEGSIZE) {
+               int rc = xen_create_contiguous_region(
+                       (unsigned long)iotlb_virt_start + (i << IO_TLB_SHIFT),
+                       get_order(IO_TLB_SEGSIZE << IO_TLB_SHIFT),
+                       IO_TLB_DMA_BITS);
+               BUG_ON(rc);
+       }
 
        /*
         * Allocate and initialize the free list array.  This array is used
@@ -167,17 +178,13 @@ swiotlb_init_with_default_size (size_t d
         */
        io_tlb_overflow_buffer = alloc_bootmem_low(io_tlb_overflow);
 
-       iotlb_bus_start = virt_to_bus(iotlb_virt_start);
-       iotlb_bus_end   = iotlb_bus_start + bytes;
-       iotlb_bus_mask  = ~(dma_addr_t)(bytes - 1);
+       iotlb_pfn_start = __pa(iotlb_virt_start) >> PAGE_SHIFT;
+       iotlb_pfn_end   = iotlb_pfn_start + (bytes >> PAGE_SHIFT);
 
        printk(KERN_INFO "Software IO TLB enabled: \n"
               " Aperture:     %lu megabytes\n"
-              " Bus range:    0x%016lx - 0x%016lx\n"
               " Kernel range: 0x%016lx - 0x%016lx\n",
               bytes >> 20,
-              (unsigned long)iotlb_bus_start,
-              (unsigned long)iotlb_bus_end,
               (unsigned long)iotlb_virt_start,
               (unsigned long)iotlb_virt_start + bytes);
 }
@@ -647,7 +654,7 @@ int
 int
 swiotlb_dma_supported (struct device *hwdev, u64 mask)
 {
-       return (mask >= (iotlb_bus_end - 1));
+       return (mask >= ((1UL << IO_TLB_DMA_BITS) - 1));
 }
 
 EXPORT_SYMBOL(swiotlb_init);
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c  Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c  Tue Jun 13 12:12:24 
2006 -0600
@@ -978,12 +978,19 @@ static void stop_hz_timer(void)
        unsigned int cpu = smp_processor_id();
        unsigned long j;
 
-       /* We must do this /before/ checking rcu_pending(). */
        cpu_set(cpu, nohz_cpu_mask);
+
+       /* See matching smp_mb in rcu_start_batch in rcupdate.c.  These mbs  */
+       /* ensure that if __rcu_pending (nested in rcu_needs_cpu) fetches a  */
+       /* value of rcp->cur that matches rdp->quiescbatch and allows us to  */
+       /* stop the hz timer then the cpumasks created for subsequent values */
+       /* of cur in rcu_start_batch are guaranteed to pick up the updated   */
+       /* nohz_cpu_mask and so will not depend on this cpu.                 */
+
        smp_mb();
 
        /* Leave ourselves in 'tick mode' if rcu or softirq pending. */
-       if (rcu_pending(cpu) || local_softirq_pending()) {
+       if (rcu_needs_cpu(cpu) || local_softirq_pending()) {
                cpu_clear(cpu, nohz_cpu_mask);
                j = jiffies + 1;
        } else {
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/arch/i386/kernel/vm86.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/vm86.c      Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/vm86.c      Tue Jun 13 12:12:24 
2006 -0600
@@ -132,7 +132,9 @@ struct pt_regs * fastcall save_v86_state
        current->thread.sysenter_cs = __KERNEL_CS;
        load_esp0(tss, &current->thread);
        current->thread.saved_esp0 = 0;
+#ifndef CONFIG_X86_NO_TSS
        put_cpu();
+#endif
 
        loadsegment(fs, current->thread.saved_fs);
        loadsegment(gs, current->thread.saved_gs);
@@ -310,7 +312,9 @@ static void do_sys_vm86(struct kernel_vm
        if (cpu_has_sep)
                tsk->thread.sysenter_cs = 0;
        load_esp0(tss, &tsk->thread);
+#ifndef CONFIG_X86_NO_TSS
        put_cpu();
+#endif
 
        tsk->thread.screen_bitmap = info->screen_bitmap;
        if (info->flags & VM86_SCREEN_BITMAP)
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/arch/i386/mm/init-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/init-xen.c      Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/mm/init-xen.c      Tue Jun 13 12:12:24 
2006 -0600
@@ -558,15 +558,11 @@ void __init paging_init(void)
 
        kmap_init();
 
-       if (!xen_feature(XENFEAT_auto_translated_physmap) ||
-           xen_start_info->shared_info >= xen_start_info->nr_pages) {
-               /* Switch to the real shared_info page, and clear the
-                * dummy page. */
-               set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
-               HYPERVISOR_shared_info =
-                       (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
-               memset(empty_zero_page, 0, sizeof(empty_zero_page));
-       }
+       /* Switch to the real shared_info page, and clear the
+        * dummy page. */
+       set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
+       HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
+       memset(empty_zero_page, 0, sizeof(empty_zero_page));
 
        /* Setup mapping of lower 1st MB */
        for (i = 0; i < NR_FIX_ISAMAPS; i++)
diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/arch/ia64/Kconfig
--- a/linux-2.6-xen-sparse/arch/ia64/Kconfig    Tue Jun 13 09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/Kconfig    Tue Jun 13 12:12:24 2006 -0600
@@ -66,7 +66,7 @@ config XEN_IA64_DOM0_VP
 
 config XEN_IA64_DOM0_NON_VP
        bool
-       depends on !(XEN && XEN_IA64_DOM0_VP)
+       depends on XEN && !XEN_IA64_DOM0_VP
        default y
        help
          dom0 P=M model
@@ -489,15 +489,39 @@ source "security/Kconfig"
 
 source "crypto/Kconfig"
 
+#
 # override default values of drivers/xen/Kconfig
-if !XEN_IA64_DOM0_VP
+#
+if XEN
+config XEN_UTIL
+       default n if XEN_IA64_DOM0_VP
+
 config HAVE_ARCH_ALLOC_SKB
-        bool
-        default n
+       default n if !XEN_IA64_DOM0_VP
 
 config HAVE_ARCH_DEV_ALLOC_SKB
-        bool
-        default n
+       default n if !XEN_IA64_DOM0_VP
+
+config XEN_BALLOON
+       default n if !XEN_IA64_DOM0_VP
+
+config XEN_SKBUFF
+       default n if !XEN_IA64_DOM0_VP
+
+config XEN_NETDEV_BACKEND
+       default n if !XEN_IA64_DOM0_VP
+
+config XEN_NETDEV_FRONTEND
+       default n if !XEN_IA64_DOM0_VP
+
+config XEN_DEVMEM
+       default n
+
+config XEN_REBOOT
+       default n
+
+config XEN_SMPBOOT
+       default n
 endif
 
 source "drivers/xen/Kconfig"
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/arch/ia64/xen-mkbuildtree-pre
--- a/linux-2.6-xen-sparse/arch/ia64/xen-mkbuildtree-pre        Tue Jun 13 
09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/xen-mkbuildtree-pre        Tue Jun 13 
12:12:24 2006 -0600
@@ -10,8 +10,3 @@
 #eventually asm-xsi-offsets needs to be part of hypervisor.h/hypercall.h
 ln -sf ../../../../xen/include/asm-ia64/asm-xsi-offsets.h include/asm-ia64/xen/
 
-#ia64 drivers/xen isn't fully functional yet, workaround...
-#also ignore core/evtchn.c which uses a different irq mechanism than ia64
-#(warning: there be dragons here if these files diverge)
-ln -sf ../../arch/ia64/xen/drivers/Makefile drivers/xen/Makefile
-ln -sf ../../../arch/ia64/xen/drivers/coreMakefile drivers/xen/core/Makefile
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c        Tue Jun 13 
09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c        Tue Jun 13 
12:12:24 2006 -0600
@@ -44,9 +44,7 @@ unsigned long end_pfn_map;
  */
 unsigned long end_user_pfn = MAXMEM>>PAGE_SHIFT;  
 
-#ifndef CONFIG_XEN
 extern struct resource code_resource, data_resource;
-#endif
 
 /* Check for some hardcoded bad areas that early boot is not allowed to touch 
*/ 
 static inline int bad_addr(unsigned long *addrp, unsigned long size)
@@ -251,8 +249,7 @@ void __init e820_reserve_resources(struc
                res->end = res->start + e820[i].size - 1;
                res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
                request_resource(&iomem_resource, res);
-#ifndef CONFIG_XEN
-               if (e820.map[i].type == E820_RAM) {
+               if (e820[i].type == E820_RAM) {
                        /*
                         *  We don't know which RAM region contains kernel data,
                         *  so we try it repeatedly and let the resource manager
@@ -264,7 +261,6 @@ void __init e820_reserve_resources(struc
                        request_resource(res, &crashk_res);
 #endif
                }
-#endif
        }
 }
 
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c      Tue Jun 13 
09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c      Tue Jun 13 
12:12:24 2006 -0600
@@ -18,6 +18,56 @@
 #include <linux/slab.h>
 #include <linux/thread_info.h>
 #include <xen/interface/physdev.h>
+
+/* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
+static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int 
extent, int new_value)
+{
+       int i;
+
+       if (new_value)
+               for (i = base; i < base + extent; i++)
+                       __set_bit(i, bitmap);
+       else
+               for (i = base; i < base + extent; i++)
+                       clear_bit(i, bitmap);
+}
+
+/*
+ * this changes the io permissions bitmap in the current task.
+ */
+asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
+{
+       struct thread_struct * t = &current->thread;
+       unsigned long *bitmap;
+       struct physdev_set_iobitmap set_iobitmap;
+
+       if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
+               return -EINVAL;
+       if (turn_on && !capable(CAP_SYS_RAWIO))
+               return -EPERM;
+
+       /*
+        * If it's the first ioperm() call in this thread's lifetime, set the
+        * IO bitmap up. ioperm() is much less timing critical than clone(),
+        * this is why we delay this operation until now:
+        */
+       if (!t->io_bitmap_ptr) {
+               bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
+               if (!bitmap)
+                       return -ENOMEM;
+
+               memset(bitmap, 0xff, IO_BITMAP_BYTES);
+               t->io_bitmap_ptr = bitmap;
+
+               set_iobitmap.bitmap   = (char *)bitmap;
+               set_iobitmap.nr_ports = IO_BITMAP_BITS;
+               HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &set_iobitmap);
+       }
+
+       set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
+
+       return 0;
+}
 
 /*
  * sys_iopl has to be used when you want to access the IO ports
@@ -47,11 +97,3 @@ asmlinkage long sys_iopl(unsigned int ne
 
        return 0;
 }
-
-/*
- * this changes the io permissions bitmap in the current task.
- */
-asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
-{
-  return turn_on ? sys_iopl(3, NULL) : 0;
-}
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c       Tue Jun 13 
09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c       Tue Jun 13 
12:12:24 2006 -0600
@@ -665,13 +665,6 @@ void __init setup_arch(char **cmdline_p)
 
        setup_xen_features();
 
-       if (xen_feature(XENFEAT_auto_translated_physmap) &&
-           xen_start_info->shared_info < xen_start_info->nr_pages) {
-               HYPERVISOR_shared_info =
-                       (shared_info_t *)__va(xen_start_info->shared_info);
-               memset(empty_zero_page, 0, sizeof(empty_zero_page));
-       }
-
        HYPERVISOR_vm_assist(VMASST_CMD_enable,
                             VMASST_TYPE_writable_pagetables);
 
@@ -699,12 +692,10 @@ void __init setup_arch(char **cmdline_p)
        init_mm.end_data = (unsigned long) &_edata;
        init_mm.brk = (unsigned long) &_end;
 
-#ifndef CONFIG_XEN
        code_resource.start = virt_to_phys(&_text);
        code_resource.end = virt_to_phys(&_etext)-1;
        data_resource.start = virt_to_phys(&_etext);
        data_resource.end = virt_to_phys(&_edata)-1;
-#endif
 
        parse_cmdline_early(cmdline_p);
 
@@ -826,14 +817,6 @@ void __init setup_arch(char **cmdline_p)
 #ifdef CONFIG_XEN
        {
                int i, j, k, fpp;
-               unsigned long va;
-
-               /* 'Initial mapping' of initrd must be destroyed. */
-               for (va = xen_start_info->mod_start;
-                    va < (xen_start_info->mod_start+xen_start_info->mod_len);
-                    va += PAGE_SIZE) {
-                       HYPERVISOR_update_va_mapping(va, __pte_ma(0), 0);
-               }
 
                if (!xen_feature(XENFEAT_auto_translated_physmap)) {
                        /* Make sure we have a large enough P->M table. */
@@ -848,14 +831,6 @@ void __init setup_arch(char **cmdline_p)
                                __pa(xen_start_info->mfn_list),
                                PFN_PHYS(PFN_UP(xen_start_info->nr_pages *
                                                sizeof(unsigned long))));
-
-                       /* Destroyed 'initial mapping' of old p2m table. */
-                       for (va = xen_start_info->mfn_list;
-                            va < (xen_start_info->mfn_list +
-                                  (xen_start_info->nr_pages*sizeof(unsigned 
long)));
-                            va += PAGE_SIZE) {
-                               HYPERVISOR_update_va_mapping(va, __pte_ma(0), 
0);
-                       }
 
                        /*
                         * Initialise the list of the frames that specify the
@@ -944,8 +919,11 @@ void __init setup_arch(char **cmdline_p)
                BUG_ON(HYPERVISOR_memory_op(XENMEM_machine_memory_map, 
&memmap));
 
                e820_reserve_resources(machine_e820, memmap.nr_entries);
-       }
-#elif !defined(CONFIG_XEN)
+       } else if (!(xen_start_info->flags & SIF_INITDOMAIN))
+               e820_reserve_resources(e820.map, e820.nr_map);
+#elif defined(CONFIG_XEN)
+       e820_reserve_resources(e820.map, e820.nr_map);
+#else
        probe_roms();
        e820_reserve_resources(e820.map, e820.nr_map);
 #endif
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/arch/x86_64/kernel/smp-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/smp-xen.c Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/smp-xen.c Tue Jun 13 12:12:24 
2006 -0600
@@ -488,7 +488,7 @@ static void smp_really_stop_cpu(void *du
 {
        smp_stop_cpu(); 
        for (;;) 
-               asm("hlt"); 
+               halt();
 } 
 
 void smp_send_stop(void)
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c    Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c    Tue Jun 13 12:12:24 
2006 -0600
@@ -666,7 +666,34 @@ void __meminit init_memory_mapping(unsig
                        set_pgd(pgd_offset_k(start), mk_kernel_pgd(pud_phys));
        }
 
-       BUG_ON(!after_bootmem && start_pfn != table_end);
+       if (!after_bootmem) {
+               BUG_ON(start_pfn != table_end);
+
+               /* Re-vector virtual addresses pointing into the initial
+                  mapping to the just-established permanent ones. */
+               xen_start_info = __va(__pa(xen_start_info));
+               xen_start_info->pt_base = (unsigned long)
+                       __va(__pa(xen_start_info->pt_base));
+               if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+                       phys_to_machine_mapping =
+                               __va(__pa(xen_start_info->mfn_list));
+                       xen_start_info->mfn_list = (unsigned long)
+                               phys_to_machine_mapping;
+               }
+               if (xen_start_info->mod_start)
+                       xen_start_info->mod_start = (unsigned long)
+                               __va(__pa(xen_start_info->mod_start));
+
+               /* Destroy the Xen-created mappings beyond the kernel image as
+                * well as the temporary mappings created above. Prevents
+                * overlap with modules area (if init mapping is very big).
+                */
+               start = PAGE_ALIGN((unsigned long)_end);
+               end   = __START_KERNEL_map + (table_end << PAGE_SHIFT);
+               for (; start < end; start += PAGE_SIZE)
+                       WARN_ON(HYPERVISOR_update_va_mapping(
+                               start, __pte_ma(0), 0));
+       }
 
        __flush_tlb_all();
 }
@@ -752,15 +779,11 @@ void __init paging_init(void)
        free_area_init_node(0, NODE_DATA(0), zones,
                            __pa(PAGE_OFFSET) >> PAGE_SHIFT, holes);
 
-       if (!xen_feature(XENFEAT_auto_translated_physmap) ||
-           xen_start_info->shared_info >= xen_start_info->nr_pages) {
-               /* Switch to the real shared_info page, and clear the
-                * dummy page. */
-               set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
-               HYPERVISOR_shared_info =
-                       (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
-               memset(empty_zero_page, 0, sizeof(empty_zero_page));
-       }
+       /* Switch to the real shared_info page, and clear the
+        * dummy page. */
+       set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
+       HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
+       memset(empty_zero_page, 0, sizeof(empty_zero_page));
 
        init_mm.context.pinned = 1;
 
@@ -859,6 +882,7 @@ void __init mem_init(void)
 void __init mem_init(void)
 {
        long codesize, reservedpages, datasize, initsize;
+       unsigned long pfn;
 
        contiguous_bitmap = alloc_bootmem_low_pages(
                (end_pfn + 2*BITS_PER_LONG) >> 3);
@@ -887,6 +911,12 @@ void __init mem_init(void)
 #else
        totalram_pages = free_all_bootmem();
 #endif
+       /* XEN: init and count pages outside initial allocation. */
+       for (pfn = xen_start_info->nr_pages; pfn < max_pfn; pfn++) {
+               ClearPageReserved(&mem_map[pfn]);
+               set_page_count(&mem_map[pfn], 1);
+               totalram_pages++;
+       }
        reservedpages = end_pfn - totalram_pages - e820_hole_size(0, end_pfn);
 
        after_bootmem = 1;
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c   Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c   Tue Jun 13 12:12:24 
2006 -0600
@@ -274,7 +274,7 @@ static int talk_to_backend(struct xenbus
 {
        const char *message = NULL;
        int err;
-       xenbus_transaction_t xbt;
+       struct xenbus_transaction xbt;
 
        err = setup_tpmring(dev, tp);
        if (err) {
@@ -331,7 +331,7 @@ static void backend_changed(struct xenbu
 static void backend_changed(struct xenbus_device *dev,
                            enum xenbus_state backend_state)
 {
-       struct tpm_private *tp = dev->data;
+       struct tpm_private *tp = dev->dev.driver_data;
        DPRINTK("\n");
 
        switch (backend_state) {
@@ -369,7 +369,7 @@ static int tpmfront_probe(struct xenbus_
        if (!tp)
                return -ENOMEM;
 
-       err = xenbus_scanf(XBT_NULL, dev->nodename,
+       err = xenbus_scanf(XBT_NIL, dev->nodename,
                           "handle", "%i", &handle);
        if (XENBUS_EXIST_ERR(err))
                return err;
@@ -380,12 +380,12 @@ static int tpmfront_probe(struct xenbus_
        }
 
        tp->dev = dev;
-       dev->data = tp;
+       dev->dev.driver_data = tp;
 
        err = talk_to_backend(dev, tp);
        if (err) {
                tpm_private_put();
-               dev->data = NULL;
+               dev->dev.driver_data = NULL;
                return err;
        }
        return 0;
@@ -394,14 +394,14 @@ static int tpmfront_probe(struct xenbus_
 
 static int tpmfront_remove(struct xenbus_device *dev)
 {
-       struct tpm_private *tp = (struct tpm_private *)dev->data;
+       struct tpm_private *tp = (struct tpm_private *)dev->dev.driver_data;
        destroy_tpmring(tp);
        return 0;
 }
 
 static int tpmfront_suspend(struct xenbus_device *dev)
 {
-       struct tpm_private *tp = (struct tpm_private *)dev->data;
+       struct tpm_private *tp = (struct tpm_private *)dev->dev.driver_data;
        u32 ctr;
 
        /* lock, so no app can send */
@@ -431,7 +431,7 @@ static int tpmfront_suspend(struct xenbu
 
 static int tpmfront_resume(struct xenbus_device *dev)
 {
-       struct tpm_private *tp = (struct tpm_private *)dev->data;
+       struct tpm_private *tp = (struct tpm_private *)dev->dev.driver_data;
        destroy_tpmring(tp);
        return talk_to_backend(dev, tp);
 }
diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/Kconfig
--- a/linux-2.6-xen-sparse/drivers/xen/Kconfig  Tue Jun 13 09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/Kconfig  Tue Jun 13 12:12:24 2006 -0600
@@ -84,19 +84,6 @@ config XEN_BLKDEV_BACKEND
          block devices to other guests via a high-performance shared-memory
          interface.
 
-config XEN_BLKDEV_TAP_BE
-        tristate "Block Tap support for backend driver (DANGEROUS)"
-        depends on XEN_BLKDEV_BACKEND
-        default n
-        help
-          If you intend to use the block tap driver, the backend domain will
-          not know the domain id of the real frontend, and so will not be able
-          to map its data pages.  This modifies the backend to attempt to map
-          from both the tap domain and the real frontend.  This presents a
-          security risk, and so should ONLY be used for development
-          with the blktap.  This option will be removed as the block drivers 
are
-          modified to use grant tables.
-
 config XEN_NETDEV_BACKEND
        tristate "Network-device backend driver"
         depends on XEN_BACKEND && NET
@@ -163,16 +150,6 @@ config XEN_NETDEV_FRONTEND
          dedicated device-driver domain, or your master control domain
          (domain 0), then you almost certainly want to say Y here.
 
-config XEN_BLKDEV_TAP
-       tristate "Block device tap driver"
-        depends on XEN_BACKEND
-       default n
-       help
-         This driver allows a VM to interact on block device channels
-         to other VMs.  Block messages may be passed through or redirected
-         to a character device, allowing device prototyping in application
-         space.  Odds are that you want to say N here.
-
 config XEN_SCRUB_PAGES
        bool "Scrub memory before freeing it to Xen"
        default y
@@ -224,8 +201,38 @@ config HAVE_ARCH_DEV_ALLOC_SKB
        bool
        default y
 
+config HAVE_IRQ_IGNORE_UNHANDLED
+       bool
+       default y
+
 config NO_IDLE_HZ
        bool
        default y
 
+config XEN_UTIL
+       bool
+       default y
+
+config XEN_BALLOON
+       bool
+       default y
+
+config XEN_DEVMEM
+       bool
+       default y
+
+config XEN_SKBUFF
+       bool
+       default y
+       depends on NET
+
+config XEN_REBOOT
+       bool
+       default y
+
+config XEN_SMPBOOT
+       bool
+       default y
+       depends on SMP
+
 endif
diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/Makefile Tue Jun 13 09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/Makefile Tue Jun 13 12:12:24 2006 -0600
@@ -1,20 +1,16 @@
-
-obj-y  += util.o
-
 obj-y  += core/
-obj-y  += char/
 obj-y  += console/
 obj-y  += evtchn/
-obj-y  += balloon/
 obj-y  += privcmd/
 obj-y  += xenbus/
 
+obj-$(CONFIG_XEN_UTIL)                 += util.o
+obj-$(CONFIG_XEN_BALLOON)              += balloon/
+obj-$(CONFIG_XEN_DEVMEM)               += char/
 obj-$(CONFIG_XEN_BLKDEV_BACKEND)       += blkback/
 obj-$(CONFIG_XEN_NETDEV_BACKEND)       += netback/
 obj-$(CONFIG_XEN_TPMDEV_BACKEND)       += tpmback/
 obj-$(CONFIG_XEN_BLKDEV_FRONTEND)      += blkfront/
 obj-$(CONFIG_XEN_NETDEV_FRONTEND)      += netfront/
-obj-$(CONFIG_XEN_BLKDEV_TAP)           += blktap/
 obj-$(CONFIG_XEN_PCIDEV_BACKEND)       += pciback/
 obj-$(CONFIG_XEN_PCIDEV_FRONTEND)      += pcifront/
-
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
--- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Tue Jun 13 
09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Tue Jun 13 
12:12:24 2006 -0600
@@ -222,7 +222,7 @@ static int increase_reservation(unsigned
                /* Update P->M and M->P tables. */
                set_phys_to_machine(pfn, frame_list[i]);
                xen_machphys_update(frame_list[i], pfn);
-            
+
                /* Link back into the page tables if not highmem. */
                if (pfn < max_low_pfn) {
                        int ret;
@@ -378,22 +378,21 @@ static void watch_target(struct xenbus_w
        unsigned long long new_target;
        int err;
 
-       err = xenbus_scanf(XBT_NULL, "memory", "target", "%llu", &new_target);
+       err = xenbus_scanf(XBT_NIL, "memory", "target", "%llu", &new_target);
        if (err != 1) {
                /* This is ok (for domain0 at least) - so just return */
                return;
-       } 
-        
+       }
+
        /* The given memory/target value is in KiB, so it needs converting to
-          pages.  PAGE_SHIFT converts bytes to pages, hence PAGE_SHIFT - 10.
-       */
+        * pages. PAGE_SHIFT converts bytes to pages, hence PAGE_SHIFT - 10.
+        */
        set_new_target(new_target >> (PAGE_SHIFT - 10));
-    
 }
 
 static int balloon_init_watcher(struct notifier_block *notifier,
-                                unsigned long event,
-                                void *data)
+                               unsigned long event,
+                               void *data)
 {
        int err;
 
@@ -402,11 +401,10 @@ static int balloon_init_watcher(struct n
                printk(KERN_ERR "Failed to set balloon watcher\n");
 
        return NOTIFY_DONE;
-    
 }
 
 static int balloon_write(struct file *file, const char __user *buffer,
-                         unsigned long count, void *data)
+                        unsigned long count, void *data)
 {
        char memstring[64], *endchar;
        unsigned long long target_bytes;
@@ -430,7 +428,7 @@ static int balloon_write(struct file *fi
 }
 
 static int balloon_read(char *page, char **start, off_t off,
-                        int count, int *eof, void *data)
+                       int count, int *eof, void *data)
 {
        int len;
 
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c        Tue Jun 13 
09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c        Tue Jun 13 
12:12:24 2006 -0600
@@ -105,24 +105,12 @@ static inline unsigned long vaddr(pendin
        (pending_grant_handles[vaddr_pagenr(_req, _seg)])
 
 
-#ifdef CONFIG_XEN_BLKDEV_TAP_BE
-/*
- * If the tap driver is used, we may get pages belonging to either the tap
- * or (more likely) the real frontend.  The backend must specify which domain
- * a given page belongs to in update_va_mapping though.  For the moment, 
- * the tap rewrites the ID field of the request to contain the request index
- * and the id of the real front end domain.
- */
-#define BLKTAP_COOKIE 0xbeadfeed
-static inline domid_t ID_TO_DOM(unsigned long id) { return (id >> 16); }
-#endif
-
 static int do_block_io_op(blkif_t *blkif);
 static void dispatch_rw_block_io(blkif_t *blkif,
                                 blkif_request_t *req,
                                 pending_req_t *pending_req);
 static void make_response(blkif_t *blkif, unsigned long id, 
-                          unsigned short op, int st);
+                         unsigned short op, int st);
 
 /******************************************************************
  * misc small helpers
@@ -446,7 +434,7 @@ static void dispatch_rw_block_io(blkif_t
                        bio = biolist[nbio++] = bio_alloc(GFP_KERNEL, nseg-i);
                        if (unlikely(bio == NULL))
                                goto fail_put_bio;
-                
+
                        bio->bi_bdev    = preq.bdev;
                        bio->bi_private = pending_req;
                        bio->bi_end_io  = end_block_io_op;
@@ -483,7 +471,7 @@ static void dispatch_rw_block_io(blkif_t
 
 
 static void make_response(blkif_t *blkif, unsigned long id, 
-                          unsigned short op, int st)
+                         unsigned short op, int st)
 {
        blkif_response_t *resp;
        unsigned long     flags;
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/blkback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Tue Jun 13 12:12:24 
2006 -0600
@@ -45,8 +45,9 @@
 #include <xen/gnttab.h>
 #include <xen/driver_util.h>
 
-#define DPRINTK(_f, _a...) pr_debug("(file=%s, line=%d) " _f, \
-                                    __FILE__ , __LINE__ , ## _a )
+#define DPRINTK(_f, _a...)                     \
+       pr_debug("(file=%s, line=%d) " _f,      \
+                __FILE__ , __LINE__ , ## _a )
 
 struct vbd {
        blkif_vdev_t   handle;      /* what the domain refers to this vbd as */
@@ -73,10 +74,6 @@ typedef struct blkif_st {
        /* Back pointer to the backend_info. */
        struct backend_info *be; 
        /* Private fields. */
-#ifdef CONFIG_XEN_BLKDEV_TAP_BE
-       /* Is this a blktap frontend */
-       unsigned int     is_blktap;
-#endif
        spinlock_t       blk_ring_lock;
        atomic_t         refcnt;
 
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Tue Jun 13 12:12:24 
2006 -0600
@@ -77,7 +77,7 @@ static ssize_t show_physical_device(stru
                                    struct device_attribute *attr, char *buf)
 {
        struct xenbus_device *dev = to_xenbus_device(_dev);
-       struct backend_info *be = dev->data;
+       struct backend_info *be = dev->dev.driver_data;
        return sprintf(buf, "%x:%x\n", be->major, be->minor);
 }
 DEVICE_ATTR(physical_device, S_IRUSR | S_IRGRP | S_IROTH,
@@ -88,7 +88,7 @@ static ssize_t show_mode(struct device *
                         char *buf)
 {
        struct xenbus_device *dev = to_xenbus_device(_dev);
-       struct backend_info *be = dev->data;
+       struct backend_info *be = dev->dev.driver_data;
        return sprintf(buf, "%s\n", be->mode);
 }
 DEVICE_ATTR(mode, S_IRUSR | S_IRGRP | S_IROTH, show_mode, NULL);
@@ -96,7 +96,7 @@ DEVICE_ATTR(mode, S_IRUSR | S_IRGRP | S_
 
 static int blkback_remove(struct xenbus_device *dev)
 {
-       struct backend_info *be = dev->data;
+       struct backend_info *be = dev->dev.driver_data;
 
        DPRINTK("");
 
@@ -116,7 +116,7 @@ static int blkback_remove(struct xenbus_
        device_remove_file(&dev->dev, &dev_attr_mode);
 
        kfree(be);
-       dev->data = NULL;
+       dev->dev.driver_data = NULL;
        return 0;
 }
 
@@ -138,7 +138,7 @@ static int blkback_probe(struct xenbus_d
                return -ENOMEM;
        }
        be->dev = dev;
-       dev->data = be;
+       dev->dev.driver_data = be;
 
        be->blkif = blkif_alloc(dev->otherend_id);
        if (IS_ERR(be->blkif)) {
@@ -186,7 +186,7 @@ static void backend_changed(struct xenbu
 
        DPRINTK("");
 
-       err = xenbus_scanf(XBT_NULL, dev->nodename, "physical-device", "%x:%x",
+       err = xenbus_scanf(XBT_NIL, dev->nodename, "physical-device", "%x:%x",
                           &major, &minor);
        if (XENBUS_EXIST_ERR(err)) {
                /* Since this watch will fire once immediately after it is
@@ -208,7 +208,7 @@ static void backend_changed(struct xenbu
                return;
        }
 
-       be->mode = xenbus_read(XBT_NULL, dev->nodename, "mode", NULL);
+       be->mode = xenbus_read(XBT_NIL, dev->nodename, "mode", NULL);
        if (IS_ERR(be->mode)) {
                err = PTR_ERR(be->mode);
                be->mode = NULL;
@@ -249,7 +249,7 @@ static void frontend_changed(struct xenb
 static void frontend_changed(struct xenbus_device *dev,
                             enum xenbus_state frontend_state)
 {
-       struct backend_info *be = dev->data;
+       struct backend_info *be = dev->dev.driver_data;
        int err;
 
        DPRINTK("");
@@ -299,7 +299,7 @@ static void frontend_changed(struct xenb
  */
 static void connect(struct backend_info *be)
 {
-       xenbus_transaction_t xbt;
+       struct xenbus_transaction xbt;
        int err;
        struct xenbus_device *dev = be->dev;
 
@@ -364,7 +364,7 @@ static int connect_ring(struct backend_i
 
        DPRINTK("%s", dev->otherend);
 
-       err = xenbus_gather(XBT_NULL, dev->otherend, "ring-ref", "%lu", 
&ring_ref,
+       err = xenbus_gather(XBT_NIL, dev->otherend, "ring-ref", "%lu", 
&ring_ref,
                            "event-channel", "%u", &evtchn, NULL);
        if (err) {
                xenbus_dev_fatal(dev, err,
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Tue Jun 13 
09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Tue Jun 13 
12:12:24 2006 -0600
@@ -83,7 +83,7 @@ static int blkfront_probe(struct xenbus_
        struct blkfront_info *info;
 
        /* FIXME: Use dynamic device id if this is not set. */
-       err = xenbus_scanf(XBT_NULL, dev->nodename,
+       err = xenbus_scanf(XBT_NIL, dev->nodename,
                           "virtual-device", "%i", &vdevice);
        if (err != 1) {
                xenbus_dev_fatal(dev, err, "reading virtual-device");
@@ -107,12 +107,12 @@ static int blkfront_probe(struct xenbus_
 
        /* Front end dir is a number, which is used as the id. */
        info->handle = simple_strtoul(strrchr(dev->nodename,'/')+1, NULL, 0);
-       dev->data = info;
+       dev->dev.driver_data = info;
 
        err = talk_to_backend(dev, info);
        if (err) {
                kfree(info);
-               dev->data = NULL;
+               dev->dev.driver_data = NULL;
                return err;
        }
 
@@ -128,7 +128,7 @@ static int blkfront_probe(struct xenbus_
  */
 static int blkfront_resume(struct xenbus_device *dev)
 {
-       struct blkfront_info *info = dev->data;
+       struct blkfront_info *info = dev->dev.driver_data;
        int err;
 
        DPRINTK("blkfront_resume: %s\n", dev->nodename);
@@ -148,7 +148,7 @@ static int talk_to_backend(struct xenbus
                           struct blkfront_info *info)
 {
        const char *message = NULL;
-       xenbus_transaction_t xbt;
+       struct xenbus_transaction xbt;
        int err;
 
        /* Create shared ring, alloc event channel. */
@@ -249,7 +249,7 @@ static void backend_changed(struct xenbu
 static void backend_changed(struct xenbus_device *dev,
                            enum xenbus_state backend_state)
 {
-       struct blkfront_info *info = dev->data;
+       struct blkfront_info *info = dev->dev.driver_data;
        struct block_device *bd;
 
        DPRINTK("blkfront:backend_changed.\n");
@@ -303,7 +303,7 @@ static void connect(struct blkfront_info
 
        DPRINTK("blkfront.c:connect:%s.\n", info->xbdev->otherend);
 
-       err = xenbus_gather(XBT_NULL, info->xbdev->otherend,
+       err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
                            "sectors", "%lu", &sectors,
                            "info", "%u", &binfo,
                            "sector-size", "%lu", &sector_size,
@@ -318,7 +318,7 @@ static void connect(struct blkfront_info
        err = xlvbd_add(sectors, info->vdevice, binfo, sector_size, info);
        if (err) {
                xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s",
-                                info->xbdev->otherend);
+                                info->xbdev->otherend);
                return;
        }
 
@@ -341,7 +341,7 @@ static void connect(struct blkfront_info
  */
 static void blkfront_closing(struct xenbus_device *dev)
 {
-       struct blkfront_info *info = dev->data;
+       struct blkfront_info *info = dev->dev.driver_data;
 
        DPRINTK("blkfront_closing: %s removed\n", dev->nodename);
 
@@ -353,7 +353,7 @@ static void blkfront_closing(struct xenb
 
 static int blkfront_remove(struct xenbus_device *dev)
 {
-       struct blkfront_info *info = dev->data;
+       struct blkfront_info *info = dev->dev.driver_data;
 
        DPRINTK("blkfront_remove: %s removed\n", dev->nodename);
 
@@ -444,7 +444,7 @@ int blkif_release(struct inode *inode, s
 
 
 int blkif_ioctl(struct inode *inode, struct file *filep,
-                unsigned command, unsigned long argument)
+               unsigned command, unsigned long argument)
 {
        int i;
 
@@ -452,10 +452,6 @@ int blkif_ioctl(struct inode *inode, str
                      command, (long)argument, inode->i_rdev);
 
        switch (command) {
-       case HDIO_GETGEO:
-               /* return ENOSYS to use defaults */
-               return -ENOSYS;
-
        case CDROMMULTISESSION:
                DPRINTK("FIXME: support multisession CDs later\n");
                for (i = 0; i < sizeof(struct cdrom_multisession); i++)
@@ -469,6 +465,23 @@ int blkif_ioctl(struct inode *inode, str
                return -EINVAL; /* same return as native Linux */
        }
 
+       return 0;
+}
+
+
+int blkif_getgeo(struct block_device *bd, struct hd_geometry *hg)
+{
+       /* We don't have real geometry info, but let's at least return
+          values consistent with the size of the device */
+       sector_t nsect = get_capacity(bd->bd_disk);
+       sector_t cylinders = nsect;
+
+       hg->heads = 0xff;
+       hg->sectors = 0x3f;
+       sector_div(cylinders, hg->heads * hg->sectors);
+       hg->cylinders = cylinders;
+       if ((sector_t)(hg->cylinders + 1) * hg->heads * hg->sectors < nsect)
+               hg->cylinders = 0xffff;
        return 0;
 }
 
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/blkfront/block.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Tue Jun 13 12:12:24 
2006 -0600
@@ -59,15 +59,15 @@
 #include <asm/uaccess.h>
 
 #if 1
-#define IPRINTK(fmt, args...) \
-    printk(KERN_INFO "xen_blk: " fmt, ##args)
+#define IPRINTK(fmt, args...)                          \
+       printk(KERN_INFO "xen_blk: " fmt, ##args)
 #else
 #define IPRINTK(fmt, args...) ((void)0)
 #endif
 
 #if 1
-#define WPRINTK(fmt, args...) \
-    printk(KERN_WARNING "xen_blk: " fmt, ##args)
+#define WPRINTK(fmt, args...)                          \
+       printk(KERN_WARNING "xen_blk: " fmt, ##args)
 #else
 #define WPRINTK(fmt, args...) ((void)0)
 #endif
@@ -139,7 +139,8 @@ extern int blkif_open(struct inode *inod
 extern int blkif_open(struct inode *inode, struct file *filep);
 extern int blkif_release(struct inode *inode, struct file *filep);
 extern int blkif_ioctl(struct inode *inode, struct file *filep,
-                       unsigned command, unsigned long argument);
+                      unsigned command, unsigned long argument);
+extern int blkif_getgeo(struct block_device *, struct hd_geometry *);
 extern int blkif_check(dev_t dev);
 extern int blkif_revalidate(dev_t dev);
 extern void do_blkif_request (request_queue_t *rq);
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c   Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c   Tue Jun 13 12:12:24 
2006 -0600
@@ -91,6 +91,7 @@ static struct block_device_operations xl
        .open = blkif_open,
        .release = blkif_release,
        .ioctl  = blkif_ioctl,
+       .getgeo = blkif_getgeo
 };
 
 DEFINE_SPINLOCK(blkif_io_lock);
diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/drivers/xen/char/mem.c
--- a/linux-2.6-xen-sparse/drivers/xen/char/mem.c       Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/char/mem.c       Tue Jun 13 12:12:24 
2006 -0600
@@ -30,10 +30,10 @@
 
 static inline int uncached_access(struct file *file)
 {
-        if (file->f_flags & O_SYNC)
-                return 1;
-        /* Xen sets correct MTRR type on non-RAM for us. */
-        return 0;
+       if (file->f_flags & O_SYNC)
+               return 1;
+       /* Xen sets correct MTRR type on non-RAM for us. */
+       return 0;
 }
 
 /*
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/console/console.c
--- a/linux-2.6-xen-sparse/drivers/xen/console/console.c        Tue Jun 13 
09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c        Tue Jun 13 
12:12:24 2006 -0600
@@ -364,7 +364,7 @@ void xencons_tx(void)
 
 /* Privileged receive callback and transmit kicker. */
 static irqreturn_t xencons_priv_interrupt(int irq, void *dev_id,
-                                          struct pt_regs *regs)
+                                         struct pt_regs *regs)
 {
        static char rbuf[16];
        int         l;
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/core/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/core/Makefile    Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/Makefile    Tue Jun 13 12:12:24 
2006 -0600
@@ -2,11 +2,13 @@
 # Makefile for the linux kernel.
 #
 
-obj-y   := evtchn.o reboot.o gnttab.o features.o
+obj-y := evtchn.o gnttab.o features.o
 
-obj-$(CONFIG_PROC_FS)     += xen_proc.o
-obj-$(CONFIG_NET)         += skbuff.o
-obj-$(CONFIG_SMP)         += smpboot.o
-obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o
-obj-$(CONFIG_SYSFS)       += hypervisor_sysfs.o
-obj-$(CONFIG_XEN_SYSFS)   += xen_sysfs.o
+obj-$(CONFIG_PROC_FS)          += xen_proc.o
+obj-$(CONFIG_SYSFS)            += hypervisor_sysfs.o
+obj-$(CONFIG_HOTPLUG_CPU)      += cpu_hotplug.o
+obj-$(CONFIG_XEN_SYSFS)                += xen_sysfs.o
+obj-$(CONFIG_IA64)             += xenia64_init.o
+obj-$(CONFIG_XEN_SKBUFF)       += skbuff.o
+obj-$(CONFIG_XEN_REBOOT)       += reboot.o
+obj-$(CONFIG_XEN_SMPBOOT)      += smpboot.o
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/core/cpu_hotplug.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/cpu_hotplug.c       Tue Jun 13 
09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/cpu_hotplug.c       Tue Jun 13 
12:12:24 2006 -0600
@@ -34,7 +34,7 @@ static void vcpu_hotplug(unsigned int cp
                return;
 
        sprintf(dir, "cpu/%d", cpu);
-       err = xenbus_scanf(XBT_NULL, dir, "availability", "%s", state);
+       err = xenbus_scanf(XBT_NIL, dir, "availability", "%s", state);
        if (err != 1) {
                printk(KERN_ERR "XENBUS: Unable to read cpu state\n");
                return;
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/core/evtchn.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c    Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c    Tue Jun 13 12:12:24 
2006 -0600
@@ -54,7 +54,8 @@ static DEFINE_SPINLOCK(irq_mapping_updat
 static DEFINE_SPINLOCK(irq_mapping_update_lock);
 
 /* IRQ <-> event-channel mappings. */
-static int evtchn_to_irq[NR_EVENT_CHANNELS] = {[0 ...  NR_EVENT_CHANNELS-1] = 
-1};
+static int evtchn_to_irq[NR_EVENT_CHANNELS] = {
+       [0 ...  NR_EVENT_CHANNELS-1] = -1 };
 
 /* Packed IRQ information: binding type, sub-type index, and event channel. */
 static u32 irq_info[NR_IRQS];
@@ -120,6 +121,11 @@ static inline unsigned long active_evtch
 
 static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
 {
+       int irq = evtchn_to_irq[chn];
+
+       BUG_ON(irq == -1);
+       set_native_irq_info(irq, cpumask_of_cpu(cpu));
+
        clear_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu_evtchn[chn]]);
        set_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu]);
        cpu_evtchn[chn] = cpu;
@@ -127,7 +133,12 @@ static void bind_evtchn_to_cpu(unsigned 
 
 static void init_evtchn_cpu_bindings(void)
 {
+       int i;
+
        /* By default all event channels notify CPU#0. */
+       for (i = 0; i < NR_IRQS; i++)
+               set_native_irq_info(i, cpumask_of_cpu(0));
+
        memset(cpu_evtchn, 0, sizeof(cpu_evtchn));
        memset(cpu_evtchn_mask[0], ~0, sizeof(cpu_evtchn_mask[0]));
 }
@@ -430,25 +441,14 @@ void unbind_from_irqhandler(unsigned int
 }
 EXPORT_SYMBOL_GPL(unbind_from_irqhandler);
 
-#ifdef CONFIG_SMP
-static void do_nothing_function(void *ign)
-{
-}
-#endif
-
 /* Rebind an evtchn so that it gets delivered to a specific cpu */
 static void rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
 {
        struct evtchn_bind_vcpu bind_vcpu;
-       int evtchn;
-
-       spin_lock(&irq_mapping_update_lock);
-
-       evtchn = evtchn_from_irq(irq);
-       if (!VALID_EVTCHN(evtchn)) {
-               spin_unlock(&irq_mapping_update_lock);
+       int evtchn = evtchn_from_irq(irq);
+
+       if (!VALID_EVTCHN(evtchn))
                return;
-       }
 
        /* Send future instances of this interrupt to other vcpu. */
        bind_vcpu.port = evtchn;
@@ -461,21 +461,6 @@ static void rebind_irq_to_cpu(unsigned i
         */
        if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0)
                bind_evtchn_to_cpu(evtchn, tcpu);
-
-       spin_unlock(&irq_mapping_update_lock);
-
-       /*
-        * Now send the new target processor a NOP IPI. When this returns, it
-        * will check for any pending interrupts, and so service any that got 
-        * delivered to the wrong processor by mistake.
-        * 
-        * XXX: The only time this is called with interrupts disabled is from
-        * the hotplug/hotunplug path. In that case, all cpus are stopped with 
-        * interrupts disabled, and the missed interrupts will be picked up
-        * when they start again. This is kind of a hack.
-        */
-       if (!irqs_disabled())
-               smp_call_function(do_nothing_function, NULL, 0, 0);
 }
 
 
@@ -597,8 +582,8 @@ static unsigned int startup_pirq(unsigne
 
        pirq_query_unmask(irq_to_pirq(irq));
 
+       evtchn_to_irq[evtchn] = irq;
        bind_evtchn_to_cpu(evtchn, 0);
-       evtchn_to_irq[evtchn] = irq;
        irq_info[irq] = mk_irq_info(IRQT_PIRQ, irq, evtchn);
 
  out:
@@ -678,7 +663,14 @@ static struct hw_interrupt_type pirq_typ
        set_affinity_irq
 };
 
-void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
+int irq_ignore_unhandled(unsigned int irq)
+{
+       struct physdev_irq_status_query irq_status = { .irq = irq };
+       (void)HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, &irq_status);
+       return !!(irq_status.flags & XENIRQSTAT_shared);
+}
+
+void resend_irq_on_evtchn(struct hw_interrupt_type *h, unsigned int i)
 {
        int evtchn = evtchn_from_irq(i);
        shared_info_t *s = HYPERVISOR_shared_info;
@@ -709,6 +701,8 @@ void unmask_evtchn(int port)
        shared_info_t *s = HYPERVISOR_shared_info;
        unsigned int cpu = smp_processor_id();
        vcpu_info_t *vcpu_info = &s->vcpu_info[cpu];
+
+       BUG_ON(!irqs_disabled());
 
        /* Slow path (hypercall) if this is a non-local port. */
        if (unlikely(cpu != cpu_from_evtchn(port))) {
@@ -726,11 +720,8 @@ void unmask_evtchn(int port)
         */
        if (synch_test_bit(port, &s->evtchn_pending[0]) &&
            !synch_test_and_set_bit(port / BITS_PER_LONG,
-                                   &vcpu_info->evtchn_pending_sel)) {
+                                   &vcpu_info->evtchn_pending_sel))
                vcpu_info->evtchn_upcall_pending = 1;
-               if (!vcpu_info->evtchn_upcall_mask)
-                       force_evtchn_callback();
-       }
 }
 EXPORT_SYMBOL_GPL(unmask_evtchn);
 
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/core/gnttab.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c    Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c    Tue Jun 13 12:12:24 
2006 -0600
@@ -1,27 +1,27 @@
 /******************************************************************************
  * gnttab.c
- * 
+ *
  * Granting foreign access to our memory reservation.
- * 
+ *
  * Copyright (c) 2005, Christopher Clark
  * Copyright (c) 2004-2005, K A Fraser
- * 
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License version 2
  * as published by the Free Software Foundation; or, when distributed
  * separately from the Linux kernel or incorporated into other
  * software packages, subject to the following license:
- * 
+ *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this source file (the "Software"), to deal in the Software without
  * restriction, including without limitation the rights to use, copy, modify,
  * merge, publish, distribute, sublicense, and/or sell copies of the Software,
  * and to permit persons to whom the Software is furnished to do so, subject to
  * the following conditions:
- * 
+ *
  * The above copyright notice and this permission notice shall be included in
  * all copies or substantial portions of the Software.
- * 
+ *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -36,45 +36,17 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
+#include <xen/interface/xen.h>
+#include <xen/gnttab.h>
 #include <asm/pgtable.h>
-#include <xen/interface/xen.h>
 #include <asm/uaccess.h>
-#include <xen/gnttab.h>
 #include <asm/synch_bitops.h>
-
-#if 1
-#define ASSERT(_p)                                                           \
-       if (!(_p)) { printk(KERN_ALERT"Assertion '%s': line %d, file %s\n",   \
-       #_p , __LINE__, __FILE__); *(int*)0=0; }
-#else
-#define ASSERT(_p) ((void)0)
-#endif
-
-#define WPRINTK(fmt, args...)                          \
-       printk(KERN_WARNING "xen_grant: " fmt, ##args)
-
-
-EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access);
-EXPORT_SYMBOL_GPL(gnttab_end_foreign_access_ref);
-EXPORT_SYMBOL_GPL(gnttab_end_foreign_access);
-EXPORT_SYMBOL_GPL(gnttab_query_foreign_access);
-EXPORT_SYMBOL_GPL(gnttab_grant_foreign_transfer);
-EXPORT_SYMBOL_GPL(gnttab_end_foreign_transfer_ref);
-EXPORT_SYMBOL_GPL(gnttab_end_foreign_transfer);
-EXPORT_SYMBOL_GPL(gnttab_alloc_grant_references);
-EXPORT_SYMBOL_GPL(gnttab_free_grant_references);
-EXPORT_SYMBOL_GPL(gnttab_free_grant_reference);
-EXPORT_SYMBOL_GPL(gnttab_empty_grant_references);
-EXPORT_SYMBOL_GPL(gnttab_claim_grant_reference);
-EXPORT_SYMBOL_GPL(gnttab_release_grant_reference);
-EXPORT_SYMBOL_GPL(gnttab_request_free_callback);
-EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access_ref);
-EXPORT_SYMBOL_GPL(gnttab_grant_foreign_transfer_ref);
 
 /* External tools reserve first few grant table entries. */
 #define NR_RESERVED_ENTRIES 8
 
-#define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
+#define NR_GRANT_ENTRIES \
+       (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(struct grant_entry))
 #define GNTTAB_LIST_END (NR_GRANT_ENTRIES + 1)
 
 static grant_ref_t gnttab_list[NR_GRANT_ENTRIES];
@@ -82,12 +54,11 @@ static grant_ref_t gnttab_free_head;
 static grant_ref_t gnttab_free_head;
 static DEFINE_SPINLOCK(gnttab_list_lock);
 
-static grant_entry_t *shared = NULL;
-
-static struct gnttab_free_callback *gnttab_free_callback_list = NULL;
-
-static int
-get_free_entries(int count)
+static struct grant_entry *shared;
+
+static struct gnttab_free_callback *gnttab_free_callback_list;
+
+static int get_free_entries(int count)
 {
        unsigned long flags;
        int ref;
@@ -109,8 +80,7 @@ get_free_entries(int count)
 
 #define get_free_entry() get_free_entries(1)
 
-static void
-do_free_callbacks(void)
+static void do_free_callbacks(void)
 {
        struct gnttab_free_callback *callback, *next;
 
@@ -130,15 +100,13 @@ do_free_callbacks(void)
        }
 }
 
-static inline void
-check_free_callbacks(void)
+static inline void check_free_callbacks(void)
 {
        if (unlikely(gnttab_free_callback_list))
                do_free_callbacks();
 }
 
-static void
-put_free_entry(grant_ref_t ref)
+static void put_free_entry(grant_ref_t ref)
 {
        unsigned long flags;
        spin_lock_irqsave(&gnttab_list_lock, flags);
@@ -153,8 +121,8 @@ put_free_entry(grant_ref_t ref)
  * Public grant-issuing interface functions
  */
 
-int
-gnttab_grant_foreign_access(domid_t domid, unsigned long frame, int readonly)
+int gnttab_grant_foreign_access(domid_t domid, unsigned long frame,
+                               int readonly)
 {
        int ref;
 
@@ -168,20 +136,20 @@ gnttab_grant_foreign_access(domid_t domi
 
        return ref;
 }
-
-void
-gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid,
-                               unsigned long frame, int readonly)
+EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access);
+
+void gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid,
+                                    unsigned long frame, int readonly)
 {
        shared[ref].frame = frame;
        shared[ref].domid = domid;
        wmb();
        shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
 }
-
-
-int
-gnttab_query_foreign_access(grant_ref_t ref)
+EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access_ref);
+
+
+int gnttab_query_foreign_access(grant_ref_t ref)
 {
        u16 nflags;
 
@@ -189,9 +157,9 @@ gnttab_query_foreign_access(grant_ref_t 
 
        return (nflags & (GTF_reading|GTF_writing));
 }
-
-int
-gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly)
+EXPORT_SYMBOL_GPL(gnttab_query_foreign_access);
+
+int gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly)
 {
        u16 flags, nflags;
 
@@ -206,15 +174,15 @@ gnttab_end_foreign_access_ref(grant_ref_
 
        return 1;
 }
-
-void
-gnttab_end_foreign_access(grant_ref_t ref, int readonly, unsigned long page)
+EXPORT_SYMBOL_GPL(gnttab_end_foreign_access_ref);
+
+void gnttab_end_foreign_access(grant_ref_t ref, int readonly,
+                              unsigned long page)
 {
        if (gnttab_end_foreign_access_ref(ref, readonly)) {
                put_free_entry(ref);
-               if (page != 0) {
+               if (page != 0)
                        free_page(page);
-               }
        } else {
                /* XXX This needs to be fixed so that the ref and page are
                   placed on a list to be freed up later. */
@@ -222,9 +190,9 @@ gnttab_end_foreign_access(grant_ref_t re
                       "WARNING: leaking g.e. and page still in use!\n");
        }
 }
-
-int
-gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn)
+EXPORT_SYMBOL_GPL(gnttab_end_foreign_access);
+
+int gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn)
 {
        int ref;
 
@@ -234,27 +202,27 @@ gnttab_grant_foreign_transfer(domid_t do
 
        return ref;
 }
-
-void
-gnttab_grant_foreign_transfer_ref(grant_ref_t ref, domid_t domid,
-                                 unsigned long pfn)
+EXPORT_SYMBOL_GPL(gnttab_grant_foreign_transfer);
+
+void gnttab_grant_foreign_transfer_ref(grant_ref_t ref, domid_t domid,
+                                      unsigned long pfn)
 {
        shared[ref].frame = pfn;
        shared[ref].domid = domid;
        wmb();
        shared[ref].flags = GTF_accept_transfer;
 }
-
-unsigned long
-gnttab_end_foreign_transfer_ref(grant_ref_t ref)
+EXPORT_SYMBOL_GPL(gnttab_grant_foreign_transfer_ref);
+
+unsigned long gnttab_end_foreign_transfer_ref(grant_ref_t ref)
 {
        unsigned long frame;
        u16           flags;
 
        /*
-         * If a transfer is not even yet started, try to reclaim the grant
-         * reference and return failure (== 0).
-         */
+        * If a transfer is not even yet started, try to reclaim the grant
+        * reference and return failure (== 0).
+        */
        while (!((flags = shared[ref].flags) & GTF_transfer_committed)) {
                if (synch_cmpxchg(&shared[ref].flags, flags, 0) == flags)
                        return 0;
@@ -274,24 +242,23 @@ gnttab_end_foreign_transfer_ref(grant_re
 
        return frame;
 }
-
-unsigned long
-gnttab_end_foreign_transfer(grant_ref_t ref)
+EXPORT_SYMBOL_GPL(gnttab_end_foreign_transfer_ref);
+
+unsigned long gnttab_end_foreign_transfer(grant_ref_t ref)
 {
        unsigned long frame = gnttab_end_foreign_transfer_ref(ref);
        put_free_entry(ref);
        return frame;
 }
-
-void
-gnttab_free_grant_reference(grant_ref_t ref)
-{
-
+EXPORT_SYMBOL_GPL(gnttab_end_foreign_transfer);
+
+void gnttab_free_grant_reference(grant_ref_t ref)
+{
        put_free_entry(ref);
 }
-
-void
-gnttab_free_grant_references(grant_ref_t head)
+EXPORT_SYMBOL_GPL(gnttab_free_grant_reference);
+
+void gnttab_free_grant_references(grant_ref_t head)
 {
        grant_ref_t ref;
        unsigned long flags;
@@ -310,9 +277,9 @@ gnttab_free_grant_references(grant_ref_t
        check_free_callbacks();
        spin_unlock_irqrestore(&gnttab_list_lock, flags);
 }
-
-int
-gnttab_alloc_grant_references(u16 count, grant_ref_t *head)
+EXPORT_SYMBOL_GPL(gnttab_free_grant_references);
+
+int gnttab_alloc_grant_references(u16 count, grant_ref_t *head)
 {
        int h = get_free_entries(count);
 
@@ -323,15 +290,15 @@ gnttab_alloc_grant_references(u16 count,
 
        return 0;
 }
-
-int
-gnttab_empty_grant_references(const grant_ref_t *private_head)
+EXPORT_SYMBOL_GPL(gnttab_alloc_grant_references);
+
+int gnttab_empty_grant_references(const grant_ref_t *private_head)
 {
        return (*private_head == GNTTAB_LIST_END);
 }
-
-int
-gnttab_claim_grant_reference(grant_ref_t *private_head)
+EXPORT_SYMBOL_GPL(gnttab_empty_grant_references);
+
+int gnttab_claim_grant_reference(grant_ref_t *private_head)
 {
        grant_ref_t g = *private_head;
        if (unlikely(g == GNTTAB_LIST_END))
@@ -339,17 +306,18 @@ gnttab_claim_grant_reference(grant_ref_t
        *private_head = gnttab_list[g];
        return g;
 }
-
-void
-gnttab_release_grant_reference(grant_ref_t *private_head, grant_ref_t  release)
+EXPORT_SYMBOL_GPL(gnttab_claim_grant_reference);
+
+void gnttab_release_grant_reference(grant_ref_t *private_head,
+                                   grant_ref_t release)
 {
        gnttab_list[release] = *private_head;
        *private_head = release;
 }
-
-void
-gnttab_request_free_callback(struct gnttab_free_callback *callback,
-                            void (*fn)(void *), void *arg, u16 count)
+EXPORT_SYMBOL_GPL(gnttab_release_grant_reference);
+
+void gnttab_request_free_callback(struct gnttab_free_callback *callback,
+                                 void (*fn)(void *), void *arg, u16 count)
 {
        unsigned long flags;
        spin_lock_irqsave(&gnttab_list_lock, flags);
@@ -361,9 +329,10 @@ gnttab_request_free_callback(struct gntt
        callback->next = gnttab_free_callback_list;
        gnttab_free_callback_list = callback;
        check_free_callbacks();
- out:
+out:
        spin_unlock_irqrestore(&gnttab_list_lock, flags);
 }
+EXPORT_SYMBOL_GPL(gnttab_request_free_callback);
 
 #ifndef __ia64__
 static int map_pte_fn(pte_t *pte, struct page *pmd_page,
@@ -377,7 +346,7 @@ static int map_pte_fn(pte_t *pte, struct
 }
 
 static int unmap_pte_fn(pte_t *pte, struct page *pmd_page,
-                     unsigned long addr, void *data)
+                       unsigned long addr, void *data)
 {
 
        set_pte_at(&init_mm, addr, pte, __pte(0));
@@ -385,10 +354,9 @@ static int unmap_pte_fn(pte_t *pte, stru
 }
 #endif
 
-int
-gnttab_resume(void)
-{
-       gnttab_setup_table_t setup;
+int gnttab_resume(void)
+{
+       struct gnttab_setup_table setup;
        unsigned long frames[NR_GRANT_FRAMES];
        int rc;
 #ifndef __ia64__
@@ -424,8 +392,7 @@ gnttab_resume(void)
        return 0;
 }
 
-int
-gnttab_suspend(void)
+int gnttab_suspend(void)
 {
 
 #ifndef __ia64__
@@ -437,8 +404,7 @@ gnttab_suspend(void)
        return 0;
 }
 
-static int __init
-gnttab_init(void)
+static int __init gnttab_init(void)
 {
        int i;
 
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/core/reboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c    Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c    Tue Jun 13 12:12:24 
2006 -0600
@@ -250,7 +250,7 @@ static void shutdown_handler(struct xenb
                             const char **vec, unsigned int len)
 {
        char *str;
-       xenbus_transaction_t xbt;
+       struct xenbus_transaction xbt;
        int err;
 
        if (shutting_down != SHUTDOWN_INVALID)
@@ -298,7 +298,7 @@ static void sysrq_handler(struct xenbus_
                          unsigned int len)
 {
        char sysrq_key = '\0';
-       xenbus_transaction_t xbt;
+       struct xenbus_transaction xbt;
        int err;
 
  again:
@@ -336,8 +336,8 @@ static struct xenbus_watch sysrq_watch =
 };
 
 static int setup_shutdown_watcher(struct notifier_block *notifier,
-                                  unsigned long event,
-                                  void *data)
+                                 unsigned long event,
+                                 void *data)
 {
        int err;
 
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/core/smpboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c   Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c   Tue Jun 13 12:12:24 
2006 -0600
@@ -89,9 +89,8 @@ void __init prefill_possible_map(void)
 
        for (i = 0; i < NR_CPUS; i++) {
                rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL);
-               if (rc == -ENOENT)
-                       break;
-               cpu_set(i, cpu_possible_map);
+               if (rc >= 0)
+                       cpu_set(i, cpu_possible_map);
        }
 }
 
@@ -209,7 +208,7 @@ void cpu_initialize_context(unsigned int
        ctxt.failsafe_callback_cs  = __KERNEL_CS;
        ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback;
 
-       ctxt.ctrlreg[3] = virt_to_mfn(swapper_pg_dir) << PAGE_SHIFT;
+       ctxt.ctrlreg[3] = xen_pfn_to_cr3(virt_to_mfn(swapper_pg_dir));
 #else /* __x86_64__ */
        ctxt.user_regs.cs = __KERNEL_CS;
        ctxt.user_regs.esp = idle->thread.rsp0 - sizeof(struct pt_regs);
@@ -221,7 +220,7 @@ void cpu_initialize_context(unsigned int
        ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback;
        ctxt.syscall_callback_eip  = (unsigned long)system_call;
 
-       ctxt.ctrlreg[3] = virt_to_mfn(init_level4_pgt) << PAGE_SHIFT;
+       ctxt.ctrlreg[3] = xen_pfn_to_cr3(virt_to_mfn(init_level4_pgt));
 
        ctxt.gs_base_kernel = (unsigned long)(cpu_pda(cpu));
 #endif
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c
--- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c  Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c  Tue Jun 13 12:12:24 
2006 -0600
@@ -93,7 +93,7 @@ void evtchn_device_upcall(int port)
 }
 
 static ssize_t evtchn_read(struct file *file, char __user *buf,
-                           size_t count, loff_t *ppos)
+                          size_t count, loff_t *ppos)
 {
        int rc;
        unsigned int c, p, bytes1 = 0, bytes2 = 0;
@@ -153,7 +153,7 @@ static ssize_t evtchn_read(struct file *
 }
 
 static ssize_t evtchn_write(struct file *file, const char __user *buf,
-                            size_t count, loff_t *ppos)
+                           size_t count, loff_t *ppos)
 {
        int  rc, i;
        evtchn_port_t *kbuf = (evtchn_port_t *)__get_free_page(GFP_KERNEL);
@@ -201,7 +201,7 @@ static void evtchn_bind_to_user(struct p
 }
 
 static int evtchn_ioctl(struct inode *inode, struct file *file,
-                        unsigned int cmd, unsigned long arg)
+                       unsigned int cmd, unsigned long arg)
 {
        int rc;
        struct per_user_data *u = file->private_data;
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/netback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Tue Jun 13 12:12:24 
2006 -0600
@@ -47,12 +47,13 @@
 #include <xen/gnttab.h>
 #include <xen/driver_util.h>
 
-#define DPRINTK(_f, _a...) pr_debug("(file=%s, line=%d) " _f, \
-                                    __FILE__ , __LINE__ , ## _a )
-#define IPRINTK(fmt, args...) \
-    printk(KERN_INFO "xen_net: " fmt, ##args)
-#define WPRINTK(fmt, args...) \
-    printk(KERN_WARNING "xen_net: " fmt, ##args)
+#define DPRINTK(_f, _a...)                     \
+       pr_debug("(file=%s, line=%d) " _f,      \
+                __FILE__ , __LINE__ , ## _a )
+#define IPRINTK(fmt, args...)                          \
+       printk(KERN_INFO "xen_net: " fmt, ##args)
+#define WPRINTK(fmt, args...)                          \
+       printk(KERN_WARNING "xen_net: " fmt, ##args)
 
 typedef struct netif_st {
        /* Unique identifier for this interface. */
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Tue Jun 13 
09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Tue Jun 13 
12:12:24 2006 -0600
@@ -124,7 +124,7 @@ netif_t *netif_alloc(domid_t domid, unsi
                 * Initialise a dummy MAC address. We choose the numerically
                 * largest non-broadcast address to prevent the address getting
                 * stolen by an Ethernet bridge for STP purposes.
-                 * (FE:FF:FF:FF:FF:FF) 
+                * (FE:FF:FF:FF:FF:FF)
                 */ 
                memset(dev->dev_addr, 0xFF, ETH_ALEN);
                dev->dev_addr[0] &= ~0x01;
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/netback/loopback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c       Tue Jun 13 
09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c       Tue Jun 13 
12:12:24 2006 -0600
@@ -146,11 +146,13 @@ static void loopback_construct(struct ne
        dev->hard_start_xmit = loopback_start_xmit;
        dev->get_stats       = loopback_get_stats;
        dev->set_multicast_list = loopback_set_multicast_list;
+       dev->change_mtu      = NULL; /* allow arbitrary mtu */
 
        dev->tx_queue_len    = 0;
 
        dev->features        = (NETIF_F_HIGHDMA |
                                NETIF_F_LLTX |
+                               NETIF_F_SG |
                                NETIF_F_IP_CSUM);
 
        SET_ETHTOOL_OPS(dev, &network_ethtool_ops);
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Tue Jun 13 
09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Tue Jun 13 
12:12:24 2006 -0600
@@ -43,14 +43,14 @@ static void netif_idx_release(u16 pendin
 static void netif_idx_release(u16 pending_idx);
 static void netif_page_release(struct page *page);
 static void make_tx_response(netif_t *netif, 
-                             u16      id,
-                             s8       st);
+                            u16      id,
+                            s8       st);
 static int  make_rx_response(netif_t *netif, 
-                             u16      id, 
-                             s8       st,
-                             u16      offset,
-                             u16      size,
-                             u16      flags);
+                            u16      id, 
+                            s8       st,
+                            u16      offset,
+                            u16      size,
+                            u16      flags);
 
 static void net_tx_action(unsigned long unused);
 static DECLARE_TASKLET(net_tx_tasklet, net_tx_action, 0);
@@ -329,9 +329,9 @@ static void net_rx_action(unsigned long 
                        DPRINTK("Bad status %d from grant transfer to DOM%u\n",
                                gop->status, netif->domid);
                        /*
-                         * Page no longer belongs to us unless GNTST_bad_page,
-                         * but that should be a fatal error anyway.
-                         */
+                        * Page no longer belongs to us unless GNTST_bad_page,
+                        * but that should be a fatal error anyway.
+                        */
                        BUG_ON(gop->status == GNTST_bad_page);
                        status = NETIF_RSP_ERROR; 
                }
@@ -458,6 +458,9 @@ inline static void net_tx_action_dealloc
        dc = dealloc_cons;
        dp = dealloc_prod;
 
+       /* Ensure we see all indexes enqueued by netif_idx_release(). */
+       smp_rmb();
+
        /*
         * Free up any grants we have finished using
         */
@@ -480,10 +483,181 @@ inline static void net_tx_action_dealloc
 
                make_tx_response(netif, pending_tx_info[pending_idx].req.id, 
                                 NETIF_RSP_OKAY);
-        
+
                pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
 
                netif_put(netif);
+       }
+}
+
+static void netbk_tx_err(netif_t *netif, RING_IDX end)
+{
+       RING_IDX cons = netif->tx.req_cons;
+
+       do {
+               netif_tx_request_t *txp = RING_GET_REQUEST(&netif->tx, cons);
+               make_tx_response(netif, txp->id, NETIF_RSP_ERROR);
+       } while (++cons < end);
+       netif->tx.req_cons = cons;
+       netif_schedule_work(netif);
+       netif_put(netif);
+}
+
+static int netbk_count_requests(netif_t *netif, netif_tx_request_t *txp,
+                               int work_to_do)
+{
+       netif_tx_request_t *first = txp;
+       RING_IDX cons = netif->tx.req_cons;
+       int frags = 1;
+
+       while (txp->flags & NETTXF_more_data) {
+               if (frags >= work_to_do) {
+                       DPRINTK("Need more frags\n");
+                       return -frags;
+               }
+
+               txp = RING_GET_REQUEST(&netif->tx, cons + frags);
+               if (txp->size > first->size) {
+                       DPRINTK("Frags galore\n");
+                       return -frags;
+               }
+
+               first->size -= txp->size;
+               frags++;
+
+               if (unlikely((txp->offset + txp->size) > PAGE_SIZE)) {
+                       DPRINTK("txp->offset: %x, size: %u\n",
+                               txp->offset, txp->size);
+                       return -frags;
+               }
+       }
+
+       return frags;
+}
+
+static gnttab_map_grant_ref_t *netbk_get_requests(netif_t *netif,
+                                                 struct sk_buff *skb,
+                                                 gnttab_map_grant_ref_t *mop)
+{
+       struct skb_shared_info *shinfo = skb_shinfo(skb);
+       skb_frag_t *frags = shinfo->frags;
+       netif_tx_request_t *txp;
+       unsigned long pending_idx = *((u16 *)skb->data);
+       RING_IDX cons = netif->tx.req_cons + 1;
+       int i, start;
+
+       /* Skip first skb fragment if it is on same page as header fragment. */
+       start = ((unsigned long)shinfo->frags[0].page == pending_idx);
+
+       for (i = start; i < shinfo->nr_frags; i++) {
+               txp = RING_GET_REQUEST(&netif->tx, cons++);
+               pending_idx = pending_ring[MASK_PEND_IDX(pending_cons++)];
+
+               gnttab_set_map_op(mop++, MMAP_VADDR(pending_idx),
+                                 GNTMAP_host_map | GNTMAP_readonly,
+                                 txp->gref, netif->domid);
+
+               memcpy(&pending_tx_info[pending_idx].req, txp, sizeof(*txp));
+               netif_get(netif);
+               pending_tx_info[pending_idx].netif = netif;
+               frags[i].page = (void *)pending_idx;
+       }
+
+       return mop;
+}
+
+static int netbk_tx_check_mop(struct sk_buff *skb,
+                              gnttab_map_grant_ref_t **mopp)
+{
+       gnttab_map_grant_ref_t *mop = *mopp;
+       int pending_idx = *((u16 *)skb->data);
+       netif_t *netif = pending_tx_info[pending_idx].netif;
+       netif_tx_request_t *txp;
+       struct skb_shared_info *shinfo = skb_shinfo(skb);
+       int nr_frags = shinfo->nr_frags;
+       int i, err, start;
+
+       /* Check status of header. */
+       err = mop->status;
+       if (unlikely(err)) {
+               txp = &pending_tx_info[pending_idx].req;
+               make_tx_response(netif, txp->id, NETIF_RSP_ERROR);
+               pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
+               netif_put(netif);
+       } else {
+               set_phys_to_machine(
+                       __pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT,
+                       FOREIGN_FRAME(mop->dev_bus_addr >> PAGE_SHIFT));
+               grant_tx_handle[pending_idx] = mop->handle;
+       }
+
+       /* Skip first skb fragment if it is on same page as header fragment. */
+       start = ((unsigned long)shinfo->frags[0].page == pending_idx);
+
+       for (i = start; i < nr_frags; i++) {
+               int j, newerr;
+
+               pending_idx = (unsigned long)shinfo->frags[i].page;
+
+               /* Check error status: if okay then remember grant handle. */
+               newerr = (++mop)->status;
+               if (likely(!newerr)) {
+                       set_phys_to_machine(
+                               __pa(MMAP_VADDR(pending_idx))>>PAGE_SHIFT,
+                               FOREIGN_FRAME(mop->dev_bus_addr>>PAGE_SHIFT));
+                       grant_tx_handle[pending_idx] = mop->handle;
+                       /* Had a previous error? Invalidate this fragment. */
+                       if (unlikely(err))
+                               netif_idx_release(pending_idx);
+                       continue;
+               }
+
+               /* Error on this fragment: respond to client with an error. */
+               txp = &pending_tx_info[pending_idx].req;
+               make_tx_response(netif, txp->id, NETIF_RSP_ERROR);
+               pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
+               netif_put(netif);
+
+               /* Not the first error? Preceding frags already invalidated. */
+               if (err)
+                       continue;
+
+               /* First error: invalidate header and preceding fragments. */
+               pending_idx = *((u16 *)skb->data);
+               netif_idx_release(pending_idx);
+               for (j = start; j < i; j++) {
+                       pending_idx = (unsigned long)shinfo->frags[i].page;
+                       netif_idx_release(pending_idx);
+               }
+
+               /* Remember the error: invalidate all subsequent fragments. */
+               err = newerr;
+       }
+
+       *mopp = mop + 1;
+       return err;
+}
+
+static void netbk_fill_frags(struct sk_buff *skb)
+{
+       struct skb_shared_info *shinfo = skb_shinfo(skb);
+       int nr_frags = shinfo->nr_frags;
+       int i;
+
+       for (i = 0; i < nr_frags; i++) {
+               skb_frag_t *frag = shinfo->frags + i;
+               netif_tx_request_t *txp;
+               unsigned long pending_idx;
+
+               pending_idx = (unsigned long)frag->page;
+               txp = &pending_tx_info[pending_idx].req;
+               frag->page = virt_to_page(MMAP_VADDR(pending_idx));
+               frag->size = txp->size;
+               frag->page_offset = txp->offset;
+
+               skb->len += txp->size;
+               skb->data_len += txp->size;
+               skb->truesize += txp->size;
        }
 }
 
@@ -504,7 +678,7 @@ static void net_tx_action(unsigned long 
                net_tx_action_dealloc();
 
        mop = tx_map_ops;
-       while ((NR_PENDING_REQS < MAX_PENDING_REQS) &&
+       while (((NR_PENDING_REQS + MAX_SKB_FRAGS) < MAX_PENDING_REQS) &&
                !list_empty(&net_schedule_list)) {
                /* Get a netif from the list with work to do. */
                ent = net_schedule_list.next;
@@ -552,38 +726,44 @@ static void net_tx_action(unsigned long 
                }
                netif->remaining_credit -= txreq.size;
 
-               netif->tx.req_cons++;
-
-               netif_schedule_work(netif);
-
-               if (unlikely(txreq.size < ETH_HLEN) || 
-                   unlikely(txreq.size > ETH_FRAME_LEN)) {
+               ret = netbk_count_requests(netif, &txreq, work_to_do);
+               if (unlikely(ret < 0)) {
+                       netbk_tx_err(netif, i - ret);
+                       continue;
+               }
+               i += ret;
+
+               if (unlikely(ret > MAX_SKB_FRAGS + 1)) {
+                       DPRINTK("Too many frags\n");
+                       netbk_tx_err(netif, i);
+                       continue;
+               }
+
+               if (unlikely(txreq.size < ETH_HLEN)) {
                        DPRINTK("Bad packet size: %d\n", txreq.size);
-                       make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
-                       netif_put(netif);
+                       netbk_tx_err(netif, i);
                        continue; 
                }
 
                /* No crossing a page as the payload mustn't fragment. */
-               if (unlikely((txreq.offset + txreq.size) >= PAGE_SIZE)) {
+               if (unlikely((txreq.offset + txreq.size) > PAGE_SIZE)) {
                        DPRINTK("txreq.offset: %x, size: %u, end: %lu\n", 
                                txreq.offset, txreq.size, 
                                (txreq.offset &~PAGE_MASK) + txreq.size);
-                       make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
-                       netif_put(netif);
+                       netbk_tx_err(netif, i);
                        continue;
                }
 
                pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)];
 
-               data_len = (txreq.size > PKT_PROT_LEN) ?
+               data_len = (txreq.size > PKT_PROT_LEN &&
+                           ret < MAX_SKB_FRAGS + 1) ?
                        PKT_PROT_LEN : txreq.size;
 
                skb = alloc_skb(data_len+16, GFP_ATOMIC);
                if (unlikely(skb == NULL)) {
                        DPRINTK("Can't allocate a skb in start_xmit.\n");
-                       make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
-                       netif_put(netif);
+                       netbk_tx_err(netif, i);
                        break;
                }
 
@@ -600,9 +780,23 @@ static void net_tx_action(unsigned long 
                pending_tx_info[pending_idx].netif = netif;
                *((u16 *)skb->data) = pending_idx;
 
+               __skb_put(skb, data_len);
+
+               skb_shinfo(skb)->nr_frags = ret - 1;
+               if (data_len < txreq.size) {
+                       skb_shinfo(skb)->nr_frags++;
+                       skb_shinfo(skb)->frags[0].page =
+                               (void *)(unsigned long)pending_idx;
+               }
+
                __skb_queue_tail(&tx_queue, skb);
 
                pending_cons++;
+
+               mop = netbk_get_requests(netif, skb, mop);
+
+               netif->tx.req_cons = i;
+               netif_schedule_work(netif);
 
                if ((mop - tx_map_ops) >= ARRAY_SIZE(tx_map_ops))
                        break;
@@ -617,75 +811,56 @@ static void net_tx_action(unsigned long 
 
        mop = tx_map_ops;
        while ((skb = __skb_dequeue(&tx_queue)) != NULL) {
+               netif_tx_request_t *txp;
+
                pending_idx = *((u16 *)skb->data);
                netif       = pending_tx_info[pending_idx].netif;
-               memcpy(&txreq, &pending_tx_info[pending_idx].req,
-                      sizeof(txreq));
+               txp         = &pending_tx_info[pending_idx].req;
 
                /* Check the remap error code. */
-               if (unlikely(mop->status)) {
+               if (unlikely(netbk_tx_check_mop(skb, &mop))) {
                        printk(KERN_ALERT "#### netback grant fails\n");
-                       make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
-                       netif_put(netif);
+                       skb_shinfo(skb)->nr_frags = 0;
                        kfree_skb(skb);
-                       mop++;
-                       pending_ring[MASK_PEND_IDX(pending_prod++)] =
-                               pending_idx;
                        continue;
                }
-               set_phys_to_machine(
-                       __pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT,
-                       FOREIGN_FRAME(mop->dev_bus_addr >> PAGE_SHIFT));
-               grant_tx_handle[pending_idx] = mop->handle;
-
-               data_len = (txreq.size > PKT_PROT_LEN) ?
-                       PKT_PROT_LEN : txreq.size;
-
-               __skb_put(skb, data_len);
+
+               data_len = skb->len;
                memcpy(skb->data, 
-                      (void *)(MMAP_VADDR(pending_idx)|txreq.offset),
+                      (void *)(MMAP_VADDR(pending_idx)|txp->offset),
                       data_len);
-               if (data_len < txreq.size) {
+               if (data_len < txp->size) {
                        /* Append the packet payload as a fragment. */
-                       skb_shinfo(skb)->frags[0].page        = 
-                               virt_to_page(MMAP_VADDR(pending_idx));
-                       skb_shinfo(skb)->frags[0].size        =
-                               txreq.size - data_len;
-                       skb_shinfo(skb)->frags[0].page_offset = 
-                               txreq.offset + data_len;
-                       skb_shinfo(skb)->nr_frags = 1;
+                       txp->offset += data_len;
+                       txp->size -= data_len;
                } else {
                        /* Schedule a response immediately. */
                        netif_idx_release(pending_idx);
                }
-
-               skb->data_len  = txreq.size - data_len;
-               skb->len      += skb->data_len;
-               skb->truesize += skb->data_len;
-
-               skb->dev      = netif->dev;
-               skb->protocol = eth_type_trans(skb, skb->dev);
 
                /*
                 * Old frontends do not assert data_validated but we
                 * can infer it from csum_blank so test both flags.
                 */
-               if (txreq.flags & (NETTXF_data_validated|NETTXF_csum_blank)) {
+               if (txp->flags & (NETTXF_data_validated|NETTXF_csum_blank)) {
                        skb->ip_summed = CHECKSUM_UNNECESSARY;
                        skb->proto_data_valid = 1;
                } else {
                        skb->ip_summed = CHECKSUM_NONE;
                        skb->proto_data_valid = 0;
                }
-               skb->proto_csum_blank = !!(txreq.flags & NETTXF_csum_blank);
-
-               netif->stats.rx_bytes += txreq.size;
+               skb->proto_csum_blank = !!(txp->flags & NETTXF_csum_blank);
+
+               netbk_fill_frags(skb);
+
+               skb->dev      = netif->dev;
+               skb->protocol = eth_type_trans(skb, skb->dev);
+
+               netif->stats.rx_bytes += skb->len;
                netif->stats.rx_packets++;
 
                netif_rx(skb);
                netif->dev->last_rx = jiffies;
-
-               mop++;
        }
 }
 
@@ -695,7 +870,10 @@ static void netif_idx_release(u16 pendin
        unsigned long flags;
 
        spin_lock_irqsave(&_lock, flags);
-       dealloc_ring[MASK_PEND_IDX(dealloc_prod++)] = pending_idx;
+       dealloc_ring[MASK_PEND_IDX(dealloc_prod)] = pending_idx;
+       /* Sync with net_tx_action_dealloc: insert idx /then/ incr producer. */
+       smp_wmb();
+       dealloc_prod++;
        spin_unlock_irqrestore(&_lock, flags);
 
        tasklet_schedule(&net_tx_tasklet);
@@ -720,8 +898,8 @@ irqreturn_t netif_be_int(int irq, void *
 }
 
 static void make_tx_response(netif_t *netif, 
-                             u16      id,
-                             s8       st)
+                            u16      id,
+                            s8       st)
 {
        RING_IDX i = netif->tx.rsp_prod_pvt;
        netif_tx_response_t *resp;
@@ -747,11 +925,11 @@ static void make_tx_response(netif_t *ne
 }
 
 static int make_rx_response(netif_t *netif, 
-                            u16      id, 
-                            s8       st,
-                            u16      offset,
-                            u16      size,
-                            u16      flags)
+                           u16      id, 
+                           s8       st,
+                           u16      offset,
+                           u16      size,
+                           u16      flags)
 {
        RING_IDX i = netif->rx.rsp_prod_pvt;
        netif_rx_response_t *resp;
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Tue Jun 13 12:12:24 
2006 -0600
@@ -44,7 +44,7 @@ static void backend_changed(struct xenbu
 
 static int netback_remove(struct xenbus_device *dev)
 {
-       struct backend_info *be = dev->data;
+       struct backend_info *be = dev->dev.driver_data;
 
        if (be->backend_watch.node) {
                unregister_xenbus_watch(&be->backend_watch);
@@ -56,7 +56,7 @@ static int netback_remove(struct xenbus_
                be->netif = NULL;
        }
        kfree(be);
-       dev->data = NULL;
+       dev->dev.driver_data = NULL;
        return 0;
 }
 
@@ -69,6 +69,8 @@ static int netback_probe(struct xenbus_d
 static int netback_probe(struct xenbus_device *dev,
                         const struct xenbus_device_id *id)
 {
+       const char *message;
+       struct xenbus_transaction xbt;
        int err;
        struct backend_info *be = kzalloc(sizeof(struct backend_info),
                                          GFP_KERNEL);
@@ -79,13 +81,34 @@ static int netback_probe(struct xenbus_d
        }
 
        be->dev = dev;
-       dev->data = be;
+       dev->dev.driver_data = be;
 
        err = xenbus_watch_path2(dev, dev->nodename, "handle",
                                 &be->backend_watch, backend_changed);
        if (err)
                goto fail;
 
+       do {
+               err = xenbus_transaction_start(&xbt);
+               if (err) {
+                       xenbus_dev_fatal(dev, err, "starting transaction");
+                       goto fail;
+               }
+
+               err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d", 1);
+               if (err) {
+                       message = "writing feature-sg";
+                       goto abort_transaction;
+               }
+
+               err = xenbus_transaction_end(xbt, 0);
+       } while (err == -EAGAIN);
+
+       if (err) {
+               xenbus_dev_fatal(dev, err, "completing transaction");
+               goto fail;
+       }
+
        err = xenbus_switch_state(dev, XenbusStateInitWait);
        if (err) {
                goto fail;
@@ -93,6 +116,9 @@ static int netback_probe(struct xenbus_d
 
        return 0;
 
+abort_transaction:
+       xenbus_transaction_end(xbt, 1);
+       xenbus_dev_fatal(dev, err, "%s", message);
 fail:
        DPRINTK("failed");
        netback_remove(dev);
@@ -108,14 +134,14 @@ static int netback_uevent(struct xenbus_
 static int netback_uevent(struct xenbus_device *xdev, char **envp,
                          int num_envp, char *buffer, int buffer_size)
 {
-       struct backend_info *be = xdev->data;
+       struct backend_info *be = xdev->dev.driver_data;
        netif_t *netif = be->netif;
        int i = 0, length = 0;
        char *val;
 
        DPRINTK("netback_uevent");
 
-       val = xenbus_read(XBT_NULL, xdev->nodename, "script", NULL);
+       val = xenbus_read(XBT_NIL, xdev->nodename, "script", NULL);
        if (IS_ERR(val)) {
                int err = PTR_ERR(val);
                xenbus_dev_fatal(xdev, err, "reading script");
@@ -151,7 +177,7 @@ static void backend_changed(struct xenbu
 
        DPRINTK("");
 
-       err = xenbus_scanf(XBT_NULL, dev->nodename, "handle", "%li", &handle);
+       err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%li", &handle);
        if (XENBUS_EXIST_ERR(err)) {
                /* Since this watch will fire once immediately after it is
                   registered, we expect this.  Ignore it, and wait for the
@@ -187,7 +213,7 @@ static void frontend_changed(struct xenb
 static void frontend_changed(struct xenbus_device *dev,
                             enum xenbus_state frontend_state)
 {
-       struct backend_info *be = dev->data;
+       struct backend_info *be = dev->dev.driver_data;
 
        DPRINTK("");
 
@@ -242,7 +268,7 @@ static void xen_net_read_rate(struct xen
        *bytes = ~0UL;
        *usec = 0;
 
-       ratestr = xenbus_read(XBT_NULL, dev->nodename, "rate", NULL);
+       ratestr = xenbus_read(XBT_NIL, dev->nodename, "rate", NULL);
        if (IS_ERR(ratestr))
                return;
 
@@ -272,7 +298,7 @@ static int xen_net_read_mac(struct xenbu
        char *s, *e, *macstr;
        int i;
 
-       macstr = s = xenbus_read(XBT_NULL, dev->nodename, "mac", NULL);
+       macstr = s = xenbus_read(XBT_NIL, dev->nodename, "mac", NULL);
        if (IS_ERR(macstr))
                return PTR_ERR(macstr);
 
@@ -321,7 +347,7 @@ static int connect_rings(struct backend_
 
        DPRINTK("");
 
-       err = xenbus_gather(XBT_NULL, dev->otherend,
+       err = xenbus_gather(XBT_NIL, dev->otherend,
                            "tx-ring-ref", "%lu", &tx_ring_ref,
                            "rx-ring-ref", "%lu", &rx_ring_ref,
                            "event-channel", "%u", &evtchn, NULL);
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Tue Jun 13 
09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Tue Jun 13 
12:12:24 2006 -0600
@@ -45,6 +45,7 @@
 #include <linux/bitops.h>
 #include <linux/ethtool.h>
 #include <linux/in.h>
+#include <linux/if_ether.h>
 #include <net/sock.h>
 #include <net/pkt_sched.h>
 #include <net/arp.h>
@@ -137,14 +138,14 @@ static inline unsigned short get_id_from
        return id;
 }
 
-#define DPRINTK(fmt, args...) pr_debug("netfront (%s:%d) " fmt, \
-                                       __FUNCTION__, __LINE__, ##args)
+#define DPRINTK(fmt, args...)                          \
+       pr_debug("netfront (%s:%d) " fmt,               \
+                __FUNCTION__, __LINE__, ##args)
 #define IPRINTK(fmt, args...)                          \
        printk(KERN_INFO "netfront: " fmt, ##args)
 #define WPRINTK(fmt, args...)                          \
        printk(KERN_WARNING "netfront: " fmt, ##args)
 
-
 static int talk_to_backend(struct xenbus_device *, struct netfront_info *);
 static int setup_device(struct xenbus_device *, struct netfront_info *);
 static struct net_device *create_netdev(int, struct xenbus_device *);
@@ -155,8 +156,6 @@ static void netif_disconnect_backend(str
 static void netif_disconnect_backend(struct netfront_info *);
 static void close_netdev(struct netfront_info *);
 static void netif_free(struct netfront_info *);
-
-static void show_device(struct netfront_info *);
 
 static void network_connect(struct net_device *);
 static void network_tx_buf_gc(struct net_device *);
@@ -172,6 +171,11 @@ static void xennet_sysfs_delif(struct ne
 #define xennet_sysfs_addif(dev) (0)
 #define xennet_sysfs_delif(dev) do { } while(0)
 #endif
+
+static inline int xennet_can_sg(struct net_device *dev)
+{
+       return dev->features & NETIF_F_SG;
+}
 
 /**
  * Entry point to this code when a new device is created.  Allocate the basic
@@ -187,7 +191,7 @@ static int __devinit netfront_probe(stru
        struct netfront_info *info;
        unsigned int handle;
 
-       err = xenbus_scanf(XBT_NULL, dev->nodename, "handle", "%u", &handle);
+       err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%u", &handle);
        if (err != 1) {
                xenbus_dev_fatal(dev, err, "reading handle");
                return err;
@@ -201,14 +205,14 @@ static int __devinit netfront_probe(stru
        }
 
        info = netdev_priv(netdev);
-       dev->data = info;
+       dev->dev.driver_data = info;
 
        err = talk_to_backend(dev, info);
        if (err) {
                xennet_sysfs_delif(info->netdev);
                unregister_netdev(netdev);
                free_netdev(netdev);
-               dev->data = NULL;
+               dev->dev.driver_data = NULL;
                return err;
        }
 
@@ -224,7 +228,7 @@ static int __devinit netfront_probe(stru
  */
 static int netfront_resume(struct xenbus_device *dev)
 {
-       struct netfront_info *info = dev->data;
+       struct netfront_info *info = dev->dev.driver_data;
 
        DPRINTK("%s\n", dev->nodename);
 
@@ -237,7 +241,7 @@ static int xen_net_read_mac(struct xenbu
        char *s, *e, *macstr;
        int i;
 
-       macstr = s = xenbus_read(XBT_NULL, dev->nodename, "mac", NULL);
+       macstr = s = xenbus_read(XBT_NIL, dev->nodename, "mac", NULL);
        if (IS_ERR(macstr))
                return PTR_ERR(macstr);
 
@@ -259,7 +263,7 @@ static int talk_to_backend(struct xenbus
                           struct netfront_info *info)
 {
        const char *message;
-       xenbus_transaction_t xbt;
+       struct xenbus_transaction xbt;
        int err;
 
        err = xen_net_read_mac(dev, info->mac);
@@ -306,8 +310,6 @@ again:
                xenbus_dev_fatal(dev, err, "completing transaction");
                goto destroy_ring;
        }
-
-       xenbus_switch_state(dev, XenbusStateConnected);
 
        return 0;
 
@@ -334,35 +336,36 @@ static int setup_device(struct xenbus_de
        info->tx.sring = NULL;
        info->irq = 0;
 
-       txs = (struct netif_tx_sring *)__get_free_page(GFP_KERNEL);
+       txs = (struct netif_tx_sring *)get_zeroed_page(GFP_KERNEL);
        if (!txs) {
                err = -ENOMEM;
                xenbus_dev_fatal(dev, err, "allocating tx ring page");
                goto fail;
        }
-       rxs = (struct netif_rx_sring *)__get_free_page(GFP_KERNEL);
+       SHARED_RING_INIT(txs);
+       FRONT_RING_INIT(&info->tx, txs, PAGE_SIZE);
+
+       err = xenbus_grant_ring(dev, virt_to_mfn(txs));
+       if (err < 0) {
+               free_page((unsigned long)txs);
+               goto fail;
+       }
+       info->tx_ring_ref = err;
+
+       rxs = (struct netif_rx_sring *)get_zeroed_page(GFP_KERNEL);
        if (!rxs) {
                err = -ENOMEM;
                xenbus_dev_fatal(dev, err, "allocating rx ring page");
                goto fail;
        }
-       memset(txs, 0, PAGE_SIZE);
-       memset(rxs, 0, PAGE_SIZE);
-
-       SHARED_RING_INIT(txs);
-       FRONT_RING_INIT(&info->tx, txs, PAGE_SIZE);
-
        SHARED_RING_INIT(rxs);
        FRONT_RING_INIT(&info->rx, rxs, PAGE_SIZE);
 
-       err = xenbus_grant_ring(dev, virt_to_mfn(txs));
-       if (err < 0)
+       err = xenbus_grant_ring(dev, virt_to_mfn(rxs));
+       if (err < 0) {
+               free_page((unsigned long)rxs);
                goto fail;
-       info->tx_ring_ref = err;
-
-       err = xenbus_grant_ring(dev, virt_to_mfn(rxs));
-       if (err < 0)
-               goto fail;
+       }
        info->rx_ring_ref = err;
 
        err = xenbus_alloc_evtchn(dev, &info->evtchn);
@@ -370,13 +373,11 @@ static int setup_device(struct xenbus_de
                goto fail;
 
        memcpy(netdev->dev_addr, info->mac, ETH_ALEN);
-       network_connect(netdev);
-       info->irq = bind_evtchn_to_irqhandler(
-               info->evtchn, netif_int, SA_SAMPLE_RANDOM, netdev->name,
-               netdev);
-       (void)send_fake_arp(netdev);
-       show_device(info);
-
+       err = bind_evtchn_to_irqhandler(info->evtchn, netif_int,
+                                       SA_SAMPLE_RANDOM, netdev->name, netdev);
+       if (err < 0)
+               goto fail;
+       info->irq = err;
        return 0;
 
  fail:
@@ -391,15 +392,23 @@ static void backend_changed(struct xenbu
 static void backend_changed(struct xenbus_device *dev,
                            enum xenbus_state backend_state)
 {
+       struct netfront_info *np = dev->dev.driver_data;
+       struct net_device *netdev = np->netdev;
+
        DPRINTK("\n");
 
        switch (backend_state) {
        case XenbusStateInitialising:
-       case XenbusStateInitWait:
        case XenbusStateInitialised:
        case XenbusStateConnected:
        case XenbusStateUnknown:
        case XenbusStateClosed:
+               break;
+
+       case XenbusStateInitWait:
+               network_connect(netdev);
+               xenbus_switch_state(dev, XenbusStateConnected);
+               (void)send_fake_arp(netdev);
                break;
 
        case XenbusStateClosing:
@@ -452,13 +461,17 @@ static int network_open(struct net_devic
        return 0;
 }
 
+static inline int netfront_tx_slot_available(struct netfront_info *np)
+{
+       return RING_FREE_REQUESTS(&np->tx) >= MAX_SKB_FRAGS + 1;
+}
+
 static inline void network_maybe_wake_tx(struct net_device *dev)
 {
        struct netfront_info *np = netdev_priv(dev);
 
        if (unlikely(netif_queue_stopped(dev)) &&
-           !RING_FULL(&np->tx) &&
-           !gnttab_empty_grant_references(&np->gref_tx_head) &&
+           netfront_tx_slot_available(np) &&
            likely(netif_running(dev)))
                netif_wake_queue(dev);
 }
@@ -485,7 +498,7 @@ static void network_tx_buf_gc(struct net
                                printk(KERN_ALERT "network_tx_buf_gc: warning "
                                       "-- grant still in use by backend "
                                       "domain.\n");
-                               break; /* bail immediately */
+                               BUG();
                        }
                        gnttab_end_foreign_access_ref(
                                np->grant_tx_ref[id], GNTMAP_readonly);
@@ -589,7 +602,7 @@ static void network_alloc_rx_buffers(str
                np->grant_rx_ref[id] = ref;
                gnttab_grant_foreign_transfer_ref(ref,
                                                  np->xbdev->otherend_id,
-                                                 __pa(skb->head) >> 
PAGE_SHIFT);
+                                                 __pa(skb->head)>>PAGE_SHIFT);
                RING_GET_REQUEST(&np->rx, req_prod + i)->gref = ref;
                np->rx_pfn_array[i] = virt_to_mfn(skb->head);
 
@@ -638,36 +651,95 @@ static void network_alloc_rx_buffers(str
        RING_PUSH_REQUESTS(&np->rx);
 }
 
+static void xennet_make_frags(struct sk_buff *skb, struct net_device *dev,
+                             struct netif_tx_request *tx)
+{
+       struct netfront_info *np = netdev_priv(dev);
+       char *data = skb->data;
+       unsigned long mfn;
+       RING_IDX prod = np->tx.req_prod_pvt;
+       int frags = skb_shinfo(skb)->nr_frags;
+       unsigned int offset = offset_in_page(data);
+       unsigned int len = skb_headlen(skb);
+       unsigned int id;
+       grant_ref_t ref;
+       int i;
+
+       while (len > PAGE_SIZE - offset) {
+               tx->size = PAGE_SIZE - offset;
+               tx->flags |= NETTXF_more_data;
+               len -= tx->size;
+               data += tx->size;
+               offset = 0;
+
+               id = get_id_from_freelist(np->tx_skbs);
+               np->tx_skbs[id] = skb_get(skb);
+               tx = RING_GET_REQUEST(&np->tx, prod++);
+               tx->id = id;
+               ref = gnttab_claim_grant_reference(&np->gref_tx_head);
+               BUG_ON((signed short)ref < 0);
+
+               mfn = virt_to_mfn(data);
+               gnttab_grant_foreign_access_ref(ref, np->xbdev->otherend_id,
+                                               mfn, GNTMAP_readonly);
+
+               tx->gref = np->grant_tx_ref[id] = ref;
+               tx->offset = offset;
+               tx->size = len;
+               tx->flags = 0;
+       }
+
+       for (i = 0; i < frags; i++) {
+               skb_frag_t *frag = skb_shinfo(skb)->frags + i;
+
+               tx->flags |= NETTXF_more_data;
+
+               id = get_id_from_freelist(np->tx_skbs);
+               np->tx_skbs[id] = skb_get(skb);
+               tx = RING_GET_REQUEST(&np->tx, prod++);
+               tx->id = id;
+               ref = gnttab_claim_grant_reference(&np->gref_tx_head);
+               BUG_ON((signed short)ref < 0);
+
+               mfn = pfn_to_mfn(page_to_pfn(frag->page));
+               gnttab_grant_foreign_access_ref(ref, np->xbdev->otherend_id,
+                                               mfn, GNTMAP_readonly);
+
+               tx->gref = np->grant_tx_ref[id] = ref;
+               tx->offset = frag->page_offset;
+               tx->size = frag->size;
+               tx->flags = 0;
+       }
+
+       np->tx.req_prod_pvt = prod;
+}
 
 static int network_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        unsigned short id;
        struct netfront_info *np = netdev_priv(dev);
        struct netif_tx_request *tx;
+       char *data = skb->data;
        RING_IDX i;
        grant_ref_t ref;
        unsigned long mfn;
        int notify;
-
-       if (unlikely((((unsigned long)skb->data & ~PAGE_MASK) + skb->len) >=
-                    PAGE_SIZE)) {
-               struct sk_buff *nskb;
-               nskb = __dev_alloc_skb(skb->len, GFP_ATOMIC|__GFP_NOWARN);
-               if (unlikely(nskb == NULL))
-                       goto drop;
-               skb_put(nskb, skb->len);
-               memcpy(nskb->data, skb->data, skb->len);
-               /* Copy only the header fields we use in this driver. */
-               nskb->dev = skb->dev;
-               nskb->ip_summed = skb->ip_summed;
-               nskb->proto_data_valid = skb->proto_data_valid;
-               dev_kfree_skb(skb);
-               skb = nskb;
+       int frags = skb_shinfo(skb)->nr_frags;
+       unsigned int offset = offset_in_page(data);
+       unsigned int len = skb_headlen(skb);
+
+       frags += (offset + len + PAGE_SIZE - 1) / PAGE_SIZE;
+       if (unlikely(frags > MAX_SKB_FRAGS + 1)) {
+               printk(KERN_ALERT "xennet: skb rides the rocket: %d frags\n",
+                      frags);
+               dump_stack();
+               goto drop;
        }
 
        spin_lock_irq(&np->tx_lock);
 
-       if (unlikely(!netif_carrier_ok(dev))) {
+       if (unlikely(!netif_carrier_ok(dev) ||
+                    (frags > 1 && !xennet_can_sg(dev)))) {
                spin_unlock_irq(&np->tx_lock);
                goto drop;
        }
@@ -682,12 +754,12 @@ static int network_start_xmit(struct sk_
        tx->id   = id;
        ref = gnttab_claim_grant_reference(&np->gref_tx_head);
        BUG_ON((signed short)ref < 0);
-       mfn = virt_to_mfn(skb->data);
+       mfn = virt_to_mfn(data);
        gnttab_grant_foreign_access_ref(
                ref, np->xbdev->otherend_id, mfn, GNTMAP_readonly);
        tx->gref = np->grant_tx_ref[id] = ref;
-       tx->offset = (unsigned long)skb->data & ~PAGE_MASK;
-       tx->size = skb->len;
+       tx->offset = offset;
+       tx->size = len;
 
        tx->flags = 0;
        if (skb->ip_summed == CHECKSUM_HW) /* local packet? */
@@ -696,14 +768,17 @@ static int network_start_xmit(struct sk_
                tx->flags |= NETTXF_data_validated;
 
        np->tx.req_prod_pvt = i + 1;
+
+       xennet_make_frags(skb, dev, tx);
+       tx->size = skb->len;
+
        RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->tx, notify);
        if (notify)
                notify_remote_via_irq(np->irq);
 
        network_tx_buf_gc(dev);
 
-       if (RING_FULL(&np->tx) ||
-           gnttab_empty_grant_references(&np->gref_tx_head))
+       if (!netfront_tx_slot_available(np))
                netif_stop_queue(dev);
 
        spin_unlock_irq(&np->tx_lock);
@@ -771,10 +846,10 @@ static int netif_poll(struct net_device 
                rx = RING_GET_RESPONSE(&np->rx, i);
 
                /*
-                 * This definitely indicates a bug, either in this driver or
-                 * in the backend driver. In future this should flag the bad
-                 * situation to the system controller to reboot the backed.
-                 */
+                * This definitely indicates a bug, either in this driver or in
+                * the backend driver. In future this should flag the bad
+                * situation to the system controller to reboot the backed.
+                */
                if ((ref = np->grant_rx_ref[rx->id]) == GRANT_INVALID_REF) {
                        WPRINTK("Bad rx response id %d.\n", rx->id);
                        work_done--;
@@ -963,12 +1038,46 @@ static struct net_device_stats *network_
        return &np->stats;
 }
 
+static int xennet_change_mtu(struct net_device *dev, int mtu)
+{
+       int max = xennet_can_sg(dev) ? 65535 - ETH_HLEN : ETH_DATA_LEN;
+
+       if (mtu > max)
+               return -EINVAL;
+       dev->mtu = mtu;
+       return 0;
+}
+
+static int xennet_set_sg(struct net_device *dev, u32 data)
+{
+       if (data) {
+               struct netfront_info *np = netdev_priv(dev);
+               int val;
+
+               if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, "feature-sg",
+                                "%d", &val) < 0)
+                       val = 0;
+               if (!val)
+                       return -ENOSYS;
+       } else if (dev->mtu > ETH_DATA_LEN)
+               dev->mtu = ETH_DATA_LEN;
+
+       return ethtool_op_set_sg(dev, data);
+}
+
+static void xennet_set_features(struct net_device *dev)
+{
+       xennet_set_sg(dev, 1);
+}
+
 static void network_connect(struct net_device *dev)
 {
        struct netfront_info *np;
        int i, requeue_idx;
        struct netif_tx_request *tx;
        struct sk_buff *skb;
+
+       xennet_set_features(dev);
 
        np = netdev_priv(dev);
        spin_lock_irq(&np->tx_lock);
@@ -1054,22 +1163,6 @@ static void network_connect(struct net_d
        spin_unlock_irq(&np->tx_lock);
 }
 
-static void show_device(struct netfront_info *np)
-{
-#ifdef DEBUG
-       if (np) {
-               IPRINTK("<vif handle=%u %s(%s) evtchn=%u tx=%p rx=%p>\n",
-                       np->handle,
-                       netif_carrier_ok(np->netdev) ? "on" : "off",
-                       netif_running(np->netdev) ? "open" : "closed",
-                       np->evtchn,
-                       np->tx,
-                       np->rx);
-       } else
-               IPRINTK("<vif NULL>\n");
-#endif
-}
-
 static void netif_uninit(struct net_device *dev)
 {
        struct netfront_info *np = netdev_priv(dev);
@@ -1081,6 +1174,8 @@ static struct ethtool_ops network_ethtoo
 {
        .get_tx_csum = ethtool_op_get_tx_csum,
        .set_tx_csum = ethtool_op_set_tx_csum,
+       .get_sg = ethtool_op_get_sg,
+       .set_sg = xennet_set_sg,
 };
 
 #ifdef CONFIG_SYSFS
@@ -1285,7 +1380,6 @@ static struct net_device * __devinit cre
        if (gnttab_alloc_grant_references(RX_MAX_TARGET,
                                          &np->gref_rx_head) < 0) {
                printk(KERN_ALERT "#### netfront can't alloc rx grant refs\n");
-               gnttab_free_grant_references(np->gref_tx_head);
                err = -ENOMEM;
                goto exit_free_tx;
        }
@@ -1297,6 +1391,7 @@ static struct net_device * __devinit cre
        netdev->poll            = netif_poll;
        netdev->set_multicast_list = network_set_multicast_list;
        netdev->uninit          = netif_uninit;
+       netdev->change_mtu      = xennet_change_mtu;
        netdev->weight          = 64;
        netdev->features        = NETIF_F_IP_CSUM;
 
@@ -1361,7 +1456,7 @@ inetdev_notify(struct notifier_block *th
  */
 static void netfront_closing(struct xenbus_device *dev)
 {
-       struct netfront_info *info = dev->data;
+       struct netfront_info *info = dev->dev.driver_data;
 
        DPRINTK("netfront_closing: %s removed\n", dev->nodename);
 
@@ -1373,7 +1468,7 @@ static void netfront_closing(struct xenb
 
 static int __devexit netfront_remove(struct xenbus_device *dev)
 {
-       struct netfront_info *info = dev->data;
+       struct netfront_info *info = dev->dev.driver_data;
 
        DPRINTK("%s\n", dev->nodename);
 
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c Tue Jun 13 12:12:24 
2006 -0600
@@ -23,7 +23,7 @@ static struct pciback_device *alloc_pdev
        dev_dbg(&xdev->dev, "allocated pdev @ 0x%p\n", pdev);
 
        pdev->xdev = xdev;
-       xdev->data = pdev;
+       xdev->dev.driver_data = pdev;
 
        spin_lock_init(&pdev->dev_lock);
 
@@ -61,7 +61,7 @@ static void free_pdev(struct pciback_dev
 
        pciback_release_devices(pdev);
 
-       pdev->xdev->data = NULL;
+       pdev->xdev->dev.driver_data = NULL;
        pdev->xdev = NULL;
 
        kfree(pdev);
@@ -125,7 +125,7 @@ static int pciback_attach(struct pciback
 
        dev_dbg(&pdev->xdev->dev, "Reading frontend config\n");
 
-       err = xenbus_gather(XBT_NULL, pdev->xdev->otherend,
+       err = xenbus_gather(XBT_NIL, pdev->xdev->otherend,
                            "pci-op-ref", "%u", &gnt_ref,
                            "event-channel", "%u", &remote_evtchn,
                            "magic", NULL, &magic, NULL);
@@ -168,7 +168,7 @@ static void pciback_frontend_changed(str
 static void pciback_frontend_changed(struct xenbus_device *xdev,
                                     enum xenbus_state fe_state)
 {
-       struct pciback_device *pdev = xdev->data;
+       struct pciback_device *pdev = xdev->dev.driver_data;
 
        dev_dbg(&xdev->dev, "fe state changed %d\n", fe_state);
 
@@ -200,7 +200,7 @@ static int pciback_publish_pci_root(stru
 
        dev_dbg(&pdev->xdev->dev, "Publishing pci roots\n");
 
-       err = xenbus_scanf(XBT_NULL, pdev->xdev->nodename,
+       err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename,
                           "root_num", "%d", &root_num);
        if (err == 0 || err == -ENOENT)
                root_num = 0;
@@ -215,7 +215,7 @@ static int pciback_publish_pci_root(stru
                        goto out;
                }
 
-               err = xenbus_scanf(XBT_NULL, pdev->xdev->nodename,
+               err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename,
                                   str, "%x:%x", &d, &b);
                if (err < 0)
                        goto out;
@@ -239,12 +239,12 @@ static int pciback_publish_pci_root(stru
        dev_dbg(&pdev->xdev->dev, "writing root %d at %04x:%02x\n",
                root_num, domain, bus);
 
-       err = xenbus_printf(XBT_NULL, pdev->xdev->nodename, str,
+       err = xenbus_printf(XBT_NIL, pdev->xdev->nodename, str,
                            "%04x:%02x", domain, bus);
        if (err)
                goto out;
 
-       err = xenbus_printf(XBT_NULL, pdev->xdev->nodename,
+       err = xenbus_printf(XBT_NIL, pdev->xdev->nodename,
                            "root_num", "%d", (root_num + 1));
 
       out:
@@ -306,7 +306,7 @@ static int pciback_setup_backend(struct 
 
        dev_dbg(&pdev->xdev->dev, "getting be setup\n");
 
-       err = xenbus_scanf(XBT_NULL, pdev->xdev->nodename, "num_devs", "%d",
+       err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, "num_devs", "%d",
                           &num_devs);
        if (err != 1) {
                if (err >= 0)
@@ -326,7 +326,7 @@ static int pciback_setup_backend(struct 
                        goto out;
                }
 
-               err = xenbus_scanf(XBT_NULL, pdev->xdev->nodename, dev_str,
+               err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, dev_str,
                                   "%x:%x:%x.%x", &domain, &bus, &slot, &func);
                if (err < 0) {
                        xenbus_dev_fatal(pdev->xdev, err,
@@ -421,7 +421,7 @@ static int pciback_xenbus_probe(struct x
 
 static int pciback_xenbus_remove(struct xenbus_device *dev)
 {
-       struct pciback_device *pdev = dev->data;
+       struct pciback_device *pdev = dev->dev.driver_data;
 
        if (pdev != NULL)
                free_pdev(pdev);
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c        Tue Jun 13 
09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c        Tue Jun 13 
12:12:24 2006 -0600
@@ -29,7 +29,7 @@ static struct pcifront_device *alloc_pde
        }
        pdev->sh_info->flags = 0;
 
-       xdev->data = pdev;
+       xdev->dev.driver_data = pdev;
        pdev->xdev = xdev;
 
        INIT_LIST_HEAD(&pdev->root_buses);
@@ -59,7 +59,7 @@ static void free_pdev(struct pcifront_de
                gnttab_end_foreign_access(pdev->gnt_ref, 0,
                                          (unsigned long)pdev->sh_info);
 
-       pdev->xdev->data = NULL;
+       pdev->xdev->dev.driver_data = NULL;
 
        kfree(pdev);
 }
@@ -67,7 +67,7 @@ static int pcifront_publish_info(struct 
 static int pcifront_publish_info(struct pcifront_device *pdev)
 {
        int err = 0;
-       xenbus_transaction_t trans;
+       struct xenbus_transaction trans;
 
        err = xenbus_grant_ring(pdev->xdev, virt_to_mfn(pdev->sh_info));
        if (err < 0)
@@ -143,7 +143,7 @@ static int pcifront_try_connect(struct p
                goto out;
        }
 
-       err = xenbus_scanf(XBT_NULL, pdev->xdev->otherend,
+       err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend,
                           "root_num", "%d", &num_roots);
        if (err == -ENOENT) {
                xenbus_dev_error(pdev->xdev, err,
@@ -165,7 +165,7 @@ static int pcifront_try_connect(struct p
                        goto out;
                }
 
-               err = xenbus_scanf(XBT_NULL, pdev->xdev->otherend, str,
+               err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, str,
                                   "%x:%x", &domain, &bus);
                if (err != 2) {
                        if (err >= 0)
@@ -216,7 +216,7 @@ static void pcifront_backend_changed(str
 static void pcifront_backend_changed(struct xenbus_device *xdev,
                                     enum xenbus_state be_state)
 {
-       struct pcifront_device *pdev = xdev->data;
+       struct pcifront_device *pdev = xdev->dev.driver_data;
 
        switch (be_state) {
        case XenbusStateClosing:
@@ -261,8 +261,8 @@ static int pcifront_xenbus_probe(struct 
 
 static int pcifront_xenbus_remove(struct xenbus_device *xdev)
 {
-       if (xdev->data)
-               free_pdev(xdev->data);
+       if (xdev->dev.driver_data)
+               free_pdev(xdev->dev.driver_data);
 
        return 0;
 }
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c
--- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c        Tue Jun 13 
09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c        Tue Jun 13 
12:12:24 2006 -0600
@@ -39,7 +39,7 @@ static DECLARE_BITMAP(hypercall_permissi
 static DECLARE_BITMAP(hypercall_permission_map, NR_HYPERCALLS);
 
 static int privcmd_ioctl(struct inode *inode, struct file *file,
-                         unsigned int cmd, unsigned long data)
+                        unsigned int cmd, unsigned long data)
 {
        int ret = -ENOSYS;
        void __user *udata = (void __user *) data;
@@ -61,11 +61,11 @@ static int privcmd_ioctl(struct inode *i
                __asm__ __volatile__ (
                        "pushl %%ebx; pushl %%ecx; pushl %%edx; "
                        "pushl %%esi; pushl %%edi; "
-                       "movl  4(%%eax),%%ebx ;"
-                       "movl  8(%%eax),%%ecx ;"
-                       "movl 12(%%eax),%%edx ;"
-                       "movl 16(%%eax),%%esi ;"
-                       "movl 20(%%eax),%%edi ;"
+                       "movl  8(%%eax),%%ebx ;"
+                       "movl 16(%%eax),%%ecx ;"
+                       "movl 24(%%eax),%%edx ;"
+                       "movl 32(%%eax),%%esi ;"
+                       "movl 40(%%eax),%%edi ;"
                        "movl   (%%eax),%%eax ;"
                        "shll $5,%%eax ;"
                        "addl $hypercall_page,%%eax ;"
@@ -161,7 +161,7 @@ static int privcmd_ioctl(struct inode *i
        case IOCTL_PRIVCMD_MMAPBATCH: {
                privcmd_mmapbatch_t m;
                struct vm_area_struct *vma = NULL;
-               unsigned long __user *p;
+               xen_pfn_t __user *p;
                unsigned long addr, mfn; 
                int i;
 
@@ -210,7 +210,7 @@ static int privcmd_ioctl(struct inode *i
        batch_err:
                printk("batch_err ret=%d vma=%p addr=%lx "
                       "num=%d arr=%p %lx-%lx\n", 
-                      ret, vma, m.addr, m.num, m.arr,
+                      ret, vma, (unsigned long)m.addr, m.num, m.arr,
                       vma ? vma->vm_start : 0, vma ? vma->vm_end : 0);
                break;
        }
@@ -241,7 +241,7 @@ static struct file_operations privcmd_fi
 };
 
 static int capabilities_read(char *page, char **start, off_t off,
-                        int count, int *eof, void *data)
+                            int count, int *eof, void *data)
 {
        int len = 0;
        *page = 0;
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/tpmback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Tue Jun 13 12:12:24 
2006 -0600
@@ -17,8 +17,9 @@
 #include <asm/io.h>
 #include <asm/pgalloc.h>
 
-#define DPRINTK(_f, _a...) pr_debug("(file=%s, line=%d) " _f, \
-                                    __FILE__ , __LINE__ , ## _a )
+#define DPRINTK(_f, _a...)                     \
+       pr_debug("(file=%s, line=%d) " _f,      \
+                __FILE__ , __LINE__ , ## _a )
 
 typedef struct tpmif_st {
        struct list_head tpmif_list;
@@ -68,12 +69,11 @@ int vtpm_release_packets(tpmif_t * tpmif
 int vtpm_release_packets(tpmif_t * tpmif, int send_msgs);
 
 #define tpmif_get(_b) (atomic_inc(&(_b)->refcnt))
-#define tpmif_put(_b)                             \
-    do {                                          \
-        if ( atomic_dec_and_test(&(_b)->refcnt) ) \
-            tpmif_disconnect_complete(_b);        \
-    } while (0)
-
+#define tpmif_put(_b)                                  \
+       do {                                            \
+               if (atomic_dec_and_test(&(_b)->refcnt)) \
+                       tpmif_disconnect_complete(_b);  \
+       } while (0)
 
 extern int num_frontends;
 
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Tue Jun 13 12:12:24 
2006 -0600
@@ -41,13 +41,13 @@ static void connect(struct backend_info 
 static void connect(struct backend_info *be);
 static int connect_ring(struct backend_info *be);
 static void backend_changed(struct xenbus_watch *watch,
-                            const char **vec, unsigned int len);
+                           const char **vec, unsigned int len);
 static void frontend_changed(struct xenbus_device *dev,
-                             enum xenbus_state frontend_state);
+                            enum xenbus_state frontend_state);
 
 static int tpmback_remove(struct xenbus_device *dev)
 {
-       struct backend_info *be = dev->data;
+       struct backend_info *be = dev->dev.driver_data;
 
        if (!be) return 0;
 
@@ -62,30 +62,30 @@ static int tpmback_remove(struct xenbus_
                be->tpmif = NULL;
        }
        kfree(be);
-       dev->data = NULL;
+       dev->dev.driver_data = NULL;
        return 0;
 }
 
 static int tpmback_probe(struct xenbus_device *dev,
-                         const struct xenbus_device_id *id)
+                        const struct xenbus_device_id *id)
 {
        int err;
        struct backend_info *be = kzalloc(sizeof(struct backend_info),
-                                         GFP_KERNEL);
+                                         GFP_KERNEL);
 
        if (!be) {
                xenbus_dev_fatal(dev, -ENOMEM,
-                                "allocating backend structure");
+                                "allocating backend structure");
                return -ENOMEM;
        }
 
        be->is_instance_set = 0;
        be->dev = dev;
-       dev->data = be;
+       dev->dev.driver_data = be;
 
        err = xenbus_watch_path2(dev, dev->nodename,
-                               "instance", &be->backend_watch,
-                               backend_changed);
+                                "instance", &be->backend_watch,
+                                backend_changed);
        if (err) {
                goto fail;
        }
@@ -102,7 +102,7 @@ fail:
 
 
 static void backend_changed(struct xenbus_watch *watch,
-                            const char **vec, unsigned int len)
+                           const char **vec, unsigned int len)
 {
        int err;
        long instance;
@@ -110,8 +110,8 @@ static void backend_changed(struct xenbu
                = container_of(watch, struct backend_info, backend_watch);
        struct xenbus_device *dev = be->dev;
 
-       err = xenbus_scanf(XBT_NULL, dev->nodename,
-                          "instance","%li", &instance);
+       err = xenbus_scanf(XBT_NIL, dev->nodename,
+                          "instance","%li", &instance);
        if (XENBUS_EXIST_ERR(err)) {
                return;
        }
@@ -129,9 +129,9 @@ static void backend_changed(struct xenbu
 
 
 static void frontend_changed(struct xenbus_device *dev,
-                             enum xenbus_state frontend_state)
-{
-       struct backend_info *be = dev->data;
+                            enum xenbus_state frontend_state)
+{
+       struct backend_info *be = dev->dev.driver_data;
        int err;
 
        be->frontend_state = frontend_state;
@@ -167,8 +167,8 @@ static void frontend_changed(struct xenb
        case XenbusStateInitWait:
        default:
                xenbus_dev_fatal(dev, -EINVAL,
-                                "saw state %d at frontend",
-                                frontend_state);
+                                "saw state %d at frontend",
+                                frontend_state);
                break;
        }
 }
@@ -188,11 +188,11 @@ static void maybe_connect(struct backend
         * Notify the vTPM manager about a new front-end.
         */
        err = tpmif_vtpm_open(be->tpmif,
-                             be->frontend_id,
-                             be->instance);
+                             be->frontend_id,
+                             be->instance);
        if (err) {
                xenbus_dev_error(be->dev, err,
-                                "queueing vtpm open packet");
+                                "queueing vtpm open packet");
                /*
                 * Should close down this device and notify FE
                 * about closure.
@@ -204,7 +204,7 @@ static void maybe_connect(struct backend
 
 static void connect(struct backend_info *be)
 {
-       xenbus_transaction_t xbt;
+       struct xenbus_transaction xbt;
        int err;
        struct xenbus_device *dev = be->dev;
        unsigned long ready = 1;
@@ -217,7 +217,7 @@ again:
        }
 
        err = xenbus_printf(xbt, be->dev->nodename,
-                           "ready", "%lu", ready);
+                           "ready", "%lu", ready);
        if (err) {
                xenbus_dev_fatal(be->dev, err, "writing 'ready'");
                goto abort;
@@ -245,8 +245,8 @@ static int connect_ring(struct backend_i
        unsigned int evtchn;
        int err;
 
-       err = xenbus_gather(XBT_NULL, dev->otherend,
-                           "ring-ref", "%lu", &ring_ref,
+       err = xenbus_gather(XBT_NIL, dev->otherend,
+                           "ring-ref", "%lu", &ring_ref,
                            "event-channel", "%u", &evtchn, NULL);
        if (err) {
                xenbus_dev_error(dev, err,
@@ -257,7 +257,7 @@ static int connect_ring(struct backend_i
 
        if (!be->tpmif) {
                be->tpmif = tpmif_find(dev->otherend_id,
-                                      be->instance);
+                                      be->instance);
                if (IS_ERR(be->tpmif)) {
                        err = PTR_ERR(be->tpmif);
                        be->tpmif = NULL;
@@ -270,8 +270,8 @@ static int connect_ring(struct backend_i
                err = tpmif_map(be->tpmif, ring_ref, evtchn);
                if (err) {
                        xenbus_dev_error(dev, err,
-                                        "mapping shared-frame %lu port %u",
-                                        ring_ref, evtchn);
+                                        "mapping shared-frame %lu port %u",
+                                        ring_ref, evtchn);
                        return err;
                }
        }
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c   Tue Jun 13 
09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c   Tue Jun 13 
12:12:24 2006 -0600
@@ -106,12 +106,12 @@ int xenbus_switch_state(struct xenbus_de
        if (state == dev->state)
                return 0;
 
-       err = xenbus_scanf(XBT_NULL, dev->nodename, "state", "%d",
+       err = xenbus_scanf(XBT_NIL, dev->nodename, "state", "%d",
                           &current_state);
        if (err != 1)
                return 0;
 
-       err = xenbus_printf(XBT_NULL, dev->nodename, "state", "%d", state);
+       err = xenbus_printf(XBT_NIL, dev->nodename, "state", "%d", state);
        if (err) {
                if (state != XenbusStateClosing) /* Avoid looping */
                        xenbus_dev_fatal(dev, err, "writing new state");
@@ -162,7 +162,7 @@ void _dev_error(struct xenbus_device *de
                goto fail;
        }
 
-       if (xenbus_write(XBT_NULL, path_buffer, "error", printf_buffer) != 0) {
+       if (xenbus_write(XBT_NIL, path_buffer, "error", printf_buffer) != 0) {
                printk("xenbus: failed to write error node for %s (%s)\n",
                       dev->nodename, printf_buffer);
                goto fail;
@@ -272,7 +272,7 @@ enum xenbus_state xenbus_read_driver_sta
 enum xenbus_state xenbus_read_driver_state(const char *path)
 {
        enum xenbus_state result;
-       int err = xenbus_gather(XBT_NULL, path, "state", "%d", &result, NULL);
+       int err = xenbus_gather(XBT_NIL, path, "state", "%d", &result, NULL);
        if (err)
                result = XenbusStateClosed;
 
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c      Tue Jun 13 
09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c      Tue Jun 13 
12:12:24 2006 -0600
@@ -51,7 +51,7 @@
 
 struct xenbus_dev_transaction {
        struct list_head list;
-       xenbus_transaction_t handle;
+       struct xenbus_transaction handle;
 };
 
 struct xenbus_dev_data {
@@ -154,11 +154,11 @@ static ssize_t xenbus_dev_write(struct f
                }
 
                if (msg_type == XS_TRANSACTION_START) {
-                       trans->handle = simple_strtoul(reply, NULL, 0);
+                       trans->handle.id = simple_strtoul(reply, NULL, 0);
                        list_add(&trans->list, &u->transactions);
                } else if (msg_type == XS_TRANSACTION_END) {
                        list_for_each_entry(trans, &u->transactions, list)
-                               if (trans->handle == u->u.msg.tx_id)
+                               if (trans->handle.id == u->u.msg.tx_id)
                                        break;
                        BUG_ON(&trans->list == &u->transactions);
                        list_del(&trans->list);
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Tue Jun 13 
09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Tue Jun 13 
12:12:24 2006 -0600
@@ -30,8 +30,9 @@
  * IN THE SOFTWARE.
  */
 
-#define DPRINTK(fmt, args...) \
-    pr_debug("xenbus_probe (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
+#define DPRINTK(fmt, args...)                          \
+       pr_debug("xenbus_probe (%s:%d) " fmt ".\n",     \
+                __FUNCTION__, __LINE__, ##args)
 
 #include <linux/kernel.h>
 #include <linux/err.h>
@@ -128,7 +129,7 @@ static int read_otherend_details(struct 
 static int read_otherend_details(struct xenbus_device *xendev,
                                 char *id_node, char *path_node)
 {
-       int err = xenbus_gather(XBT_NULL, xendev->nodename,
+       int err = xenbus_gather(XBT_NIL, xendev->nodename,
                                id_node, "%i", &xendev->otherend_id,
                                path_node, NULL, &xendev->otherend,
                                NULL);
@@ -139,7 +140,7 @@ static int read_otherend_details(struct 
                return err;
        }
        if (strlen(xendev->otherend) == 0 ||
-           !xenbus_exists(XBT_NULL, xendev->otherend, "")) {
+           !xenbus_exists(XBT_NIL, xendev->otherend, "")) {
                xenbus_dev_fatal(xendev, -ENOENT, "missing other end from %s",
                                 xendev->nodename);
                free_otherend_details(xendev);
@@ -195,14 +196,14 @@ static int backend_bus_id(char bus_id[BU
 
        devid = strrchr(nodename, '/') + 1;
 
-       err = xenbus_gather(XBT_NULL, nodename, "frontend-id", "%i", &domid,
+       err = xenbus_gather(XBT_NIL, nodename, "frontend-id", "%i", &domid,
                            "frontend", NULL, &frontend,
                            NULL);
        if (err)
                return err;
        if (strlen(frontend) == 0)
                err = -ERANGE;
-       if (!err && !xenbus_exists(XBT_NULL, frontend, ""))
+       if (!err && !xenbus_exists(XBT_NIL, frontend, ""))
                err = -ENOENT;
 
        kfree(frontend);
@@ -634,7 +635,7 @@ static int xenbus_probe_backend(const ch
        if (!nodename)
                return -ENOMEM;
 
-       dir = xenbus_directory(XBT_NULL, nodename, "", &dir_n);
+       dir = xenbus_directory(XBT_NIL, nodename, "", &dir_n);
        if (IS_ERR(dir)) {
                kfree(nodename);
                return PTR_ERR(dir);
@@ -657,7 +658,7 @@ static int xenbus_probe_device_type(stru
        unsigned int dir_n = 0;
        int i;
 
-       dir = xenbus_directory(XBT_NULL, bus->root, type, &dir_n);
+       dir = xenbus_directory(XBT_NIL, bus->root, type, &dir_n);
        if (IS_ERR(dir))
                return PTR_ERR(dir);
 
@@ -676,7 +677,7 @@ static int xenbus_probe_devices(struct x
        char **dir;
        unsigned int i, dir_n;
 
-       dir = xenbus_directory(XBT_NULL, bus->root, "", &dir_n);
+       dir = xenbus_directory(XBT_NIL, bus->root, "", &dir_n);
        if (IS_ERR(dir))
                return PTR_ERR(dir);
 
@@ -722,7 +723,7 @@ static void dev_changed(const char *node
        if (char_count(node, '/') < 2)
                return;
 
-       exists = xenbus_exists(XBT_NULL, node, "");
+       exists = xenbus_exists(XBT_NIL, node, "");
        if (!exists) {
                xenbus_cleanup_devices(node, &bus->bus);
                return;
@@ -806,6 +807,7 @@ static int resume_dev(struct device *dev
 
        if (dev->driver == NULL)
                return 0;
+
        drv = to_xenbus_driver(dev->driver);
        xdev = container_of(dev, struct xenbus_device, dev);
 
@@ -817,6 +819,18 @@ static int resume_dev(struct device *dev
                return err;
        }
 
+       xdev->state = XenbusStateInitialising;
+
+       if (drv->resume) {
+               err = drv->resume(xdev);
+               if (err) { 
+                       printk(KERN_WARNING
+                              "xenbus: resume %s failed: %i\n", 
+                              dev->bus_id, err);
+                       return err; 
+               }
+       }
+
        err = watch_otherend(xdev);
        if (err) {
                printk(KERN_WARNING
@@ -825,14 +839,7 @@ static int resume_dev(struct device *dev
                return err;
        }
 
-       xdev->state = XenbusStateInitialising;
-
-       if (drv->resume)
-               err = drv->resume(xdev);
-       if (err)
-               printk(KERN_WARNING
-                      "xenbus: resume %s failed: %i\n", dev->bus_id, err);
-       return err;
+       return 0; 
 }
 
 void xenbus_suspend(void)
@@ -939,7 +946,7 @@ static int xsd_kva_mmap(struct file *fil
 }
 
 static int xsd_kva_read(char *page, char **start, off_t off,
-                        int count, int *eof, void *data)
+                       int count, int *eof, void *data)
 {
        int len;
 
@@ -1038,10 +1045,10 @@ static int __init xenbus_probe_init(void
                free_page(page);
 
        /*
-         * Do not unregister the xenbus front/backend buses here. The
-         * buses must exist because front/backend drivers will use
-         * them when they are registered.
-         */
+        * Do not unregister the xenbus front/backend buses here. The buses
+        * must exist because front/backend drivers will use them when they are
+        * registered.
+        */
 
        return err;
 }
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Tue Jun 13 
09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Tue Jun 13 
12:12:24 2006 -0600
@@ -192,7 +192,7 @@ void *xenbus_dev_request_and_reply(struc
 }
 
 /* Send message to xs, get kmalloc'ed reply.  ERR_PTR() on error. */
-static void *xs_talkv(xenbus_transaction_t t,
+static void *xs_talkv(struct xenbus_transaction t,
                      enum xsd_sockmsg_type type,
                      const struct kvec *iovec,
                      unsigned int num_vecs,
@@ -203,7 +203,7 @@ static void *xs_talkv(xenbus_transaction
        unsigned int i;
        int err;
 
-       msg.tx_id = t;
+       msg.tx_id = t.id;
        msg.req_id = 0;
        msg.type = type;
        msg.len = 0;
@@ -251,7 +251,7 @@ static void *xs_talkv(xenbus_transaction
 }
 
 /* Simplified version of xs_talkv: single message. */
-static void *xs_single(xenbus_transaction_t t,
+static void *xs_single(struct xenbus_transaction t,
                       enum xsd_sockmsg_type type,
                       const char *string,
                       unsigned int *len)
@@ -318,7 +318,7 @@ static char **split(char *strings, unsig
        return ret;
 }
 
-char **xenbus_directory(xenbus_transaction_t t,
+char **xenbus_directory(struct xenbus_transaction t,
                        const char *dir, const char *node, unsigned int *num)
 {
        char *strings, *path;
@@ -338,7 +338,7 @@ EXPORT_SYMBOL_GPL(xenbus_directory);
 EXPORT_SYMBOL_GPL(xenbus_directory);
 
 /* Check if a path exists. Return 1 if it does. */
-int xenbus_exists(xenbus_transaction_t t,
+int xenbus_exists(struct xenbus_transaction t,
                  const char *dir, const char *node)
 {
        char **d;
@@ -356,7 +356,7 @@ EXPORT_SYMBOL_GPL(xenbus_exists);
  * Returns a kmalloced value: call free() on it after use.
  * len indicates length in bytes.
  */
-void *xenbus_read(xenbus_transaction_t t,
+void *xenbus_read(struct xenbus_transaction t,
                  const char *dir, const char *node, unsigned int *len)
 {
        char *path;
@@ -375,7 +375,7 @@ EXPORT_SYMBOL_GPL(xenbus_read);
 /* Write the value of a single file.
  * Returns -err on failure.
  */
-int xenbus_write(xenbus_transaction_t t,
+int xenbus_write(struct xenbus_transaction t,
                 const char *dir, const char *node, const char *string)
 {
        const char *path;
@@ -398,7 +398,7 @@ EXPORT_SYMBOL_GPL(xenbus_write);
 EXPORT_SYMBOL_GPL(xenbus_write);
 
 /* Create a new directory. */
-int xenbus_mkdir(xenbus_transaction_t t,
+int xenbus_mkdir(struct xenbus_transaction t,
                 const char *dir, const char *node)
 {
        char *path;
@@ -415,7 +415,7 @@ EXPORT_SYMBOL_GPL(xenbus_mkdir);
 EXPORT_SYMBOL_GPL(xenbus_mkdir);
 
 /* Destroy a file or directory (directories must be empty). */
-int xenbus_rm(xenbus_transaction_t t, const char *dir, const char *node)
+int xenbus_rm(struct xenbus_transaction t, const char *dir, const char *node)
 {
        char *path;
        int ret;
@@ -433,19 +433,19 @@ EXPORT_SYMBOL_GPL(xenbus_rm);
 /* Start a transaction: changes by others will not be seen during this
  * transaction, and changes will not be visible to others until end.
  */
-int xenbus_transaction_start(xenbus_transaction_t *t)
+int xenbus_transaction_start(struct xenbus_transaction *t)
 {
        char *id_str;
 
        down_read(&xs_state.suspend_mutex);
 
-       id_str = xs_single(XBT_NULL, XS_TRANSACTION_START, "", NULL);
+       id_str = xs_single(XBT_NIL, XS_TRANSACTION_START, "", NULL);
        if (IS_ERR(id_str)) {
                up_read(&xs_state.suspend_mutex);
                return PTR_ERR(id_str);
        }
 
-       *t = simple_strtoul(id_str, NULL, 0);
+       t->id = simple_strtoul(id_str, NULL, 0);
        kfree(id_str);
        return 0;
 }
@@ -454,7 +454,7 @@ EXPORT_SYMBOL_GPL(xenbus_transaction_sta
 /* End a transaction.
  * If abandon is true, transaction is discarded instead of committed.
  */
-int xenbus_transaction_end(xenbus_transaction_t t, int abort)
+int xenbus_transaction_end(struct xenbus_transaction t, int abort)
 {
        char abortstr[2];
        int err;
@@ -473,7 +473,7 @@ EXPORT_SYMBOL_GPL(xenbus_transaction_end
 EXPORT_SYMBOL_GPL(xenbus_transaction_end);
 
 /* Single read and scanf: returns -errno or num scanned. */
-int xenbus_scanf(xenbus_transaction_t t,
+int xenbus_scanf(struct xenbus_transaction t,
                 const char *dir, const char *node, const char *fmt, ...)
 {
        va_list ap;
@@ -496,7 +496,7 @@ EXPORT_SYMBOL_GPL(xenbus_scanf);
 EXPORT_SYMBOL_GPL(xenbus_scanf);
 
 /* Single printf and write: returns -errno or 0. */
-int xenbus_printf(xenbus_transaction_t t,
+int xenbus_printf(struct xenbus_transaction t,
                  const char *dir, const char *node, const char *fmt, ...)
 {
        va_list ap;
@@ -522,7 +522,7 @@ EXPORT_SYMBOL_GPL(xenbus_printf);
 EXPORT_SYMBOL_GPL(xenbus_printf);
 
 /* Takes tuples of names, scanf-style args, and void **, NULL terminated. */
-int xenbus_gather(xenbus_transaction_t t, const char *dir, ...)
+int xenbus_gather(struct xenbus_transaction t, const char *dir, ...)
 {
        va_list ap;
        const char *name;
@@ -560,7 +560,7 @@ static int xs_watch(const char *path, co
        iov[1].iov_base = (void *)token;
        iov[1].iov_len = strlen(token) + 1;
 
-       return xs_error(xs_talkv(XBT_NULL, XS_WATCH, iov,
+       return xs_error(xs_talkv(XBT_NIL, XS_WATCH, iov,
                                 ARRAY_SIZE(iov), NULL));
 }
 
@@ -573,7 +573,7 @@ static int xs_unwatch(const char *path, 
        iov[1].iov_base = (char *)token;
        iov[1].iov_len = strlen(token) + 1;
 
-       return xs_error(xs_talkv(XBT_NULL, XS_UNWATCH, iov,
+       return xs_error(xs_talkv(XBT_NIL, XS_UNWATCH, iov,
                                 ARRAY_SIZE(iov), NULL));
 }
 
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hw_irq.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hw_irq.h       Tue Jun 
13 09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hw_irq.h       Tue Jun 
13 12:12:24 2006 -0600
@@ -68,6 +68,10 @@ extern atomic_t irq_mis_count;
 
 #define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs))
 
-extern void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i);
+extern void resend_irq_on_evtchn(struct hw_interrupt_type *h, unsigned int i);
+static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
+{
+       resend_irq_on_evtchn(h, i);
+}
 
 #endif /* _ASM_HW_IRQ_H */
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h    Tue Jun 
13 09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h    Tue Jun 
13 12:12:24 2006 -0600
@@ -255,6 +255,7 @@ HYPERVISOR_event_channel_op(
                op.cmd = cmd;
                memcpy(&op.u, arg, sizeof(op.u));
                rc = _hypercall1(int, event_channel_op_compat, &op);
+               memcpy(arg, &op.u, sizeof(op.u));
        }
        return rc;
 }
@@ -290,6 +291,7 @@ HYPERVISOR_physdev_op(
                op.cmd = cmd;
                memcpy(&op.u, arg, sizeof(op.u));
                rc = _hypercall1(int, physdev_op_compat, &op);
+               memcpy(arg, &op.u, sizeof(op.u));
        }
        return rc;
 }
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h       Tue Jun 
13 09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h       Tue Jun 
13 12:12:24 2006 -0600
@@ -116,10 +116,12 @@ __asm__ __volatile__ ("movw %%dx,%1\n\t"
        __asm__ ( \
                "movl %%cr3,%0\n\t" \
                :"=r" (__dummy)); \
-       machine_to_phys(__dummy); \
+       __dummy = xen_cr3_to_pfn(__dummy); \
+       mfn_to_pfn(__dummy) << PAGE_SHIFT; \
 })
 #define write_cr3(x) ({                                                \
-       maddr_t __dummy = phys_to_machine(x);                   \
+       unsigned int __dummy = pfn_to_mfn((x) >> PAGE_SHIFT);   \
+       __dummy = xen_pfn_to_cr3(__dummy);                      \
        __asm__ __volatile__("movl %0,%%cr3": :"r" (__dummy));  \
 })
 
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h  Tue Jun 
13 09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h  Tue Jun 
13 12:12:24 2006 -0600
@@ -61,13 +61,6 @@ static void __init machine_specific_arch
                .address = { __KERNEL_CS, (unsigned long)nmi },
        };
 
-       if (xen_feature(XENFEAT_auto_translated_physmap) &&
-           xen_start_info->shared_info < xen_start_info->nr_pages) {
-               HYPERVISOR_shared_info =
-                       (shared_info_t *)__va(xen_start_info->shared_info);
-               memset(empty_zero_page, 0, sizeof(empty_zero_page));
-       }
-
        ret = HYPERVISOR_callback_op(CALLBACKOP_register, &event);
        if (ret == 0)
                ret = HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe);
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/include/asm-ia64/hw_irq.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/hw_irq.h    Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-ia64/hw_irq.h    Tue Jun 13 12:12:24 
2006 -0600
@@ -90,15 +90,18 @@ extern void ia64_send_ipi (int cpu, int 
 extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int 
redirect);
 extern void register_percpu_irq (ia64_vector vec, struct irqaction *action);
 
-#ifndef CONFIG_XEN
 static inline void
 hw_resend_irq (struct hw_interrupt_type *h, unsigned int vector)
 {
+#ifdef CONFIG_XEN
+       extern void resend_irq_on_evtchn(struct hw_interrupt_type *h,
+                                        unsigned int i);
+       if (is_running_on_xen())
+               resend_irq_on_evtchn(h, vector);
+       else
+#endif /* CONFIG_XEN */
        platform_send_ipi(smp_processor_id(), vector, IA64_IPI_DM_INT, 0);
 }
-#else
-extern void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i);
-#endif /* CONFIG_XEN */
 
 /*
  * Default implementations for the irq-descriptor API:
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/include/asm-ia64/page.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/page.h      Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-ia64/page.h      Tue Jun 13 12:12:24 
2006 -0600
@@ -327,6 +327,16 @@ machine_to_phys_for_dma(unsigned long ma
 #define virt_to_mfn(virt)              (__pa(virt) >> PAGE_SHIFT)
 #define virt_to_machine(virt)          __pa(virt) // for tpmfront.c
 
+static inline unsigned long
+mfn_to_local_pfn(unsigned long mfn)
+{
+       extern unsigned long max_mapnr;
+       unsigned long pfn = mfn_to_pfn(mfn);
+       if (!pfn_valid(pfn))
+               return INVALID_P2M_ENTRY;
+       return pfn;
+}
+
 #endif /* CONFIG_XEN_IA64_DOM0_VP */
 #endif /* CONFIG_XEN */
 #endif /* __ASSEMBLY__ */
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hw_irq.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hw_irq.h     Tue Jun 
13 09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hw_irq.h     Tue Jun 
13 12:12:24 2006 -0600
@@ -132,7 +132,11 @@ __asm__( \
        "push $" #nr "-256 ; " \
        "jmp common_interrupt");
 
-extern void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i);
+extern void resend_irq_on_evtchn(struct hw_interrupt_type *h, unsigned int i);
+static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
+{
+       resend_irq_on_evtchn(h, i);
+}
 
 #define platform_legacy_irq(irq)       ((irq) < 16)
 
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h  Tue Jun 
13 09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h  Tue Jun 
13 12:12:24 2006 -0600
@@ -253,6 +253,7 @@ HYPERVISOR_event_channel_op(
                op.cmd = cmd;
                memcpy(&op.u, arg, sizeof(op.u));
                rc = _hypercall1(int, event_channel_op_compat, &op);
+               memcpy(arg, &op.u, sizeof(op.u));
        }
        return rc;
 }
@@ -288,6 +289,7 @@ HYPERVISOR_physdev_op(
                op.cmd = cmd;
                memcpy(&op.u, arg, sizeof(op.u));
                rc = _hypercall1(int, physdev_op_compat, &op);
+               memcpy(arg, &op.u, sizeof(op.u));
        }
        return rc;
 }
diff -r b8f6089cbce3 -r e74c47d073ee 
linux-2.6-xen-sparse/include/xen/public/privcmd.h
--- a/linux-2.6-xen-sparse/include/xen/public/privcmd.h Tue Jun 13 09:00:32 
2006 -0600
+++ b/linux-2.6-xen-sparse/include/xen/public/privcmd.h Tue Jun 13 12:12:24 
2006 -0600
@@ -33,20 +33,22 @@
 #ifndef __LINUX_PUBLIC_PRIVCMD_H__
 #define __LINUX_PUBLIC_PRIVCMD_H__
 
+#include <linux/types.h>
+
 #ifndef __user
 #define __user
 #endif
 
 typedef struct privcmd_hypercall
 {
-       unsigned long op;
-       unsigned long arg[5];
+       __u64 op;
+       __u64 arg[5];
 } privcmd_hypercall_t;
 
 typedef struct privcmd_mmap_entry {
-       unsigned long va;
-       unsigned long mfn;
-       unsigned long npages;
+       __u64 va;
+       __u64 mfn;
+       __u64 npages;
 } privcmd_mmap_entry_t; 
 
 typedef struct privcmd_mmap {
@@ -58,8 +60,8 @@ typedef struct privcmd_mmapbatch {
 typedef struct privcmd_mmapbatch {
        int num;     /* number of pages to populate */
        domid_t dom; /* target domain */
-       unsigned long addr;  /* virtual address */
-       unsigned long __user *arr; /* array of mfns - top nibble set on err */
+       __u64 addr;  /* virtual address */
+       xen_pfn_t __user *arr; /* array of mfns - top nibble set on err */
 } privcmd_mmapbatch_t; 
 
 /*
diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/include/xen/xenbus.h
--- a/linux-2.6-xen-sparse/include/xen/xenbus.h Tue Jun 13 09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/include/xen/xenbus.h Tue Jun 13 12:12:24 2006 -0600
@@ -41,8 +41,6 @@
 #include <xen/interface/grant_table.h>
 #include <xen/interface/io/xenbus.h>
 #include <xen/interface/io/xs_wire.h>
-
-#define XBT_NULL 0
 
 /* Register callback to watch this node. */
 struct xenbus_watch
@@ -76,7 +74,6 @@ struct xenbus_device {
        struct xenbus_watch otherend_watch;
        struct device dev;
        enum xenbus_state state;
-       void *data;
 };
 
 static inline struct xenbus_device *to_xenbus_device(struct device *dev)
@@ -116,35 +113,41 @@ int xenbus_register_backend(struct xenbu
 int xenbus_register_backend(struct xenbus_driver *drv);
 void xenbus_unregister_driver(struct xenbus_driver *drv);
 
-typedef u32 xenbus_transaction_t;
-
-char **xenbus_directory(xenbus_transaction_t t,
+struct xenbus_transaction
+{
+       u32 id;
+};
+
+/* Nil transaction ID. */
+#define XBT_NIL ((struct xenbus_transaction) { 0 })
+
+char **xenbus_directory(struct xenbus_transaction t,
                        const char *dir, const char *node, unsigned int *num);
-void *xenbus_read(xenbus_transaction_t t,
+void *xenbus_read(struct xenbus_transaction t,
                  const char *dir, const char *node, unsigned int *len);
-int xenbus_write(xenbus_transaction_t t,
+int xenbus_write(struct xenbus_transaction t,
                 const char *dir, const char *node, const char *string);
-int xenbus_mkdir(xenbus_transaction_t t,
+int xenbus_mkdir(struct xenbus_transaction t,
                 const char *dir, const char *node);
-int xenbus_exists(xenbus_transaction_t t,
+int xenbus_exists(struct xenbus_transaction t,
                  const char *dir, const char *node);
-int xenbus_rm(xenbus_transaction_t t, const char *dir, const char *node);
-int xenbus_transaction_start(xenbus_transaction_t *t);
-int xenbus_transaction_end(xenbus_transaction_t t, int abort);
+int xenbus_rm(struct xenbus_transaction t, const char *dir, const char *node);
+int xenbus_transaction_start(struct xenbus_transaction *t);
+int xenbus_transaction_end(struct xenbus_transaction t, int abort);
 
 /* Single read and scanf: returns -errno or num scanned if > 0. */
-int xenbus_scanf(xenbus_transaction_t t,
+int xenbus_scanf(struct xenbus_transaction t,
                 const char *dir, const char *node, const char *fmt, ...)
        __attribute__((format(scanf, 4, 5)));
 
 /* Single printf and write: returns -errno or 0. */
-int xenbus_printf(xenbus_transaction_t t,
+int xenbus_printf(struct xenbus_transaction t,
                  const char *dir, const char *node, const char *fmt, ...)
        __attribute__((format(printf, 4, 5)));
 
 /* Generic read function: NULL-terminated triples of name,
  * sprintf-style type string, and pointer. Returns 0 or errno.*/
-int xenbus_gather(xenbus_transaction_t t, const char *dir, ...);
+int xenbus_gather(struct xenbus_transaction t, const char *dir, ...);
 
 /* notifer routines for when the xenstore comes up */
 int register_xenstore_notifier(struct notifier_block *nb);
diff -r b8f6089cbce3 -r e74c47d073ee linux-2.6-xen-sparse/mm/memory.c
--- a/linux-2.6-xen-sparse/mm/memory.c  Tue Jun 13 09:00:32 2006 -0600
+++ b/linux-2.6-xen-sparse/mm/memory.c  Tue Jun 13 12:12:24 2006 -0600
@@ -968,7 +968,6 @@ int get_user_pages(struct task_struct *t
 {
        int i;
        unsigned int vm_flags;
-       int xenpage = 0;
 
        /* 
         * Require read or write permissions.
@@ -1026,7 +1025,6 @@ int get_user_pages(struct task_struct *t
                if (vma && (vma->vm_flags & VM_FOREIGN)) {
                        struct page **map = vma->vm_private_data;
                        int offset = (start - vma->vm_start) >> PAGE_SHIFT;
-                       xenpage =1;
                        if (map[offset] != NULL) {
                                if (pages) {
                                        struct page *page = map[offset];
diff -r b8f6089cbce3 -r e74c47d073ee tools/debugger/libxendebug/xendebug.c
--- a/tools/debugger/libxendebug/xendebug.c     Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/debugger/libxendebug/xendebug.c     Tue Jun 13 12:12:24 2006 -0600
@@ -57,7 +57,7 @@ typedef struct domain_context           
     vcpu_guest_context_t context[MAX_VIRT_CPUS];
 
     long            total_pages;
-    unsigned long  *page_array;
+    xen_pfn_t      *page_array;
 
     unsigned long   cr3_phys[MAX_VIRT_CPUS];
     unsigned long  *cr3_virt[MAX_VIRT_CPUS];
@@ -346,8 +346,9 @@ xendebug_memory_page (domain_context_p c
         ctxt->cr3_phys[vcpu] = vcpu_ctxt->ctrlreg[3];
         if ( ctxt->cr3_virt[vcpu] )
             munmap(ctxt->cr3_virt[vcpu], PAGE_SIZE);
-        ctxt->cr3_virt[vcpu] = xc_map_foreign_range(xc_handle, ctxt->domid,
-                    PAGE_SIZE, PROT_READ, ctxt->cr3_phys[vcpu] >> PAGE_SHIFT);
+        ctxt->cr3_virt[vcpu] = xc_map_foreign_range(
+            xc_handle, ctxt->domid, PAGE_SIZE, PROT_READ,
+            xen_cr3_to_pfn(ctxt->cr3_phys[vcpu]));
         if ( ctxt->cr3_virt[vcpu] == NULL )
             return 0;
     } 
diff -r b8f6089cbce3 -r e74c47d073ee tools/examples/network-bridge
--- a/tools/examples/network-bridge     Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/examples/network-bridge     Tue Jun 13 12:12:24 2006 -0600
@@ -60,6 +60,7 @@ evalVariables "$@"
 evalVariables "$@"
 
 vifnum=${vifnum:-$(ip route list | awk '/^default / { print $NF }' | sed 
's/^[^0-9]*//')}
+vifnum=${vifnum:-0}
 bridge=${bridge:-xenbr${vifnum}}
 netdev=${netdev:-eth${vifnum}}
 antispoof=${antispoof:-no}
diff -r b8f6089cbce3 -r e74c47d073ee tools/firmware/hvmloader/Makefile
--- a/tools/firmware/hvmloader/Makefile Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/firmware/hvmloader/Makefile Tue Jun 13 12:12:24 2006 -0600
@@ -51,8 +51,8 @@ hvmloader: roms.h hvmloader.c acpi_madt.
        $(OBJCOPY) hvmloader.tmp hvmloader
        rm -f hvmloader.tmp
 
-roms.h:        ../rombios/BIOS-bochs-8-processors 
../vgabios/VGABIOS-lgpl-latest.bin ../vgabios/VGABIOS-lgpl-latest.cirrus.bin 
../vmxassist/vmxassist.bin
-       sh ./mkhex rombios ../rombios/BIOS-bochs-8-processors > roms.h
+roms.h:        ../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin 
../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../vmxassist/vmxassist.bin
+       sh ./mkhex rombios ../rombios/BIOS-bochs-latest > roms.h
        sh ./mkhex vgabios_stdvga ../vgabios/VGABIOS-lgpl-latest.bin >> roms.h
        sh ./mkhex vgabios_cirrusvga ../vgabios/VGABIOS-lgpl-latest.cirrus.bin 
>> roms.h
        sh ./mkhex vmxassist ../vmxassist/vmxassist.bin >> roms.h
diff -r b8f6089cbce3 -r e74c47d073ee tools/firmware/rombios/Makefile
--- a/tools/firmware/rombios/Makefile   Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/firmware/rombios/Makefile   Tue Jun 13 12:12:24 2006 -0600
@@ -1,7 +1,7 @@
-#BIOS_BUILDS = BIOS-bochs-latest
+BIOS_BUILDS = BIOS-bochs-latest
 #BIOS_BUILDS += BIOS-bochs-2-processors
 #BIOS_BUILDS += BIOS-bochs-4-processors
-BIOS_BUILDS += BIOS-bochs-8-processors
+#BIOS_BUILDS += BIOS-bochs-8-processors
 
 .PHONY: all
 all: bios
diff -r b8f6089cbce3 -r e74c47d073ee tools/firmware/vgabios/clext.c
--- a/tools/firmware/vgabios/clext.c    Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/firmware/vgabios/clext.c    Tue Jun 13 12:12:24 2006 -0600
@@ -525,6 +525,13 @@ cirrus_set_video_mode_extended:
 cirrus_set_video_mode_extended:
   call cirrus_switch_mode
   pop ax ;; mode
+  test al, #0x80
+  jnz cirrus_set_video_mode_extended_1
+  push ax
+  mov ax, #0xffff ; set to 0xff to keep win 2K happy
+  call cirrus_clear_vram
+  pop ax
+cirrus_set_video_mode_extended_1:
   and al, #0x7f
 
   push ds
@@ -992,6 +999,13 @@ cirrus_vesa_02h_1:
   jnz cirrus_vesa_02h_3
   call cirrus_enable_16k_granularity
 cirrus_vesa_02h_3:
+  test bx, #0x8000 ;; no clear
+  jnz cirrus_vesa_02h_4
+  push ax
+  xor ax,ax
+  call cirrus_clear_vram
+  pop ax
+cirrus_vesa_02h_4:
   pop ax
   push ds
 #ifdef CIRRUS_VESA3_PMINFO
@@ -1460,6 +1474,38 @@ cirrus_get_start_addr:
   pop  bx
   ret
 
+cirrus_clear_vram:
+  pusha
+  push es
+  mov si, ax
+
+  call cirrus_enable_16k_granularity
+  call cirrus_extbios_85h
+  shl al, #2
+  mov bl, al
+  xor ah,ah
+cirrus_clear_vram_1:
+  mov al, #0x09
+  mov dx, #0x3ce
+  out dx, ax
+  push ax
+  mov cx, #0xa000
+  mov es, cx
+  xor di, di
+  mov ax, si
+  mov cx, #8192
+  cld
+  rep
+      stosw
+  pop ax
+  inc ah
+  cmp ah, bl
+  jne cirrus_clear_vram_1
+
+  pop es
+  popa
+  ret
+
 cirrus_extbios_handlers:
   ;; 80h
   dw cirrus_extbios_80h
diff -r b8f6089cbce3 -r e74c47d073ee tools/firmware/vmxassist/vm86.c
--- a/tools/firmware/vmxassist/vm86.c   Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/firmware/vmxassist/vm86.c   Tue Jun 13 12:12:24 2006 -0600
@@ -36,6 +36,8 @@
 
 static unsigned prev_eip = 0;
 enum vm86_mode mode = 0;
+
+static struct regs saved_rm_regs;
 
 #ifdef DEBUG
 int traceset = 0;
@@ -795,6 +797,8 @@ protected_mode(struct regs *regs)
        oldctx.esp = regs->uesp;
        oldctx.eflags = regs->eflags;
 
+       memset(&saved_rm_regs, 0, sizeof(struct regs));
+
        /* reload all segment registers */
        if (!load_seg(regs->cs, &oldctx.cs_base,
                                &oldctx.cs_limit, &oldctx.cs_arbytes))
@@ -808,6 +812,7 @@ protected_mode(struct regs *regs)
                load_seg(0, &oldctx.es_base,
                            &oldctx.es_limit, &oldctx.es_arbytes);
                oldctx.es_sel = 0;
+               saved_rm_regs.ves = regs->ves;
        }
 
        if (load_seg(regs->uss, &oldctx.ss_base,
@@ -817,6 +822,7 @@ protected_mode(struct regs *regs)
                load_seg(0, &oldctx.ss_base,
                            &oldctx.ss_limit, &oldctx.ss_arbytes);
                oldctx.ss_sel = 0;
+               saved_rm_regs.uss = regs->uss;
        }
 
        if (load_seg(regs->vds, &oldctx.ds_base,
@@ -826,6 +832,7 @@ protected_mode(struct regs *regs)
                load_seg(0, &oldctx.ds_base,
                            &oldctx.ds_limit, &oldctx.ds_arbytes);
                oldctx.ds_sel = 0;
+               saved_rm_regs.vds = regs->vds;
        }
 
        if (load_seg(regs->vfs, &oldctx.fs_base,
@@ -835,6 +842,7 @@ protected_mode(struct regs *regs)
                load_seg(0, &oldctx.fs_base,
                            &oldctx.fs_limit, &oldctx.fs_arbytes);
                oldctx.fs_sel = 0;
+               saved_rm_regs.vfs = regs->vfs;
        }
 
        if (load_seg(regs->vgs, &oldctx.gs_base,
@@ -844,6 +852,7 @@ protected_mode(struct regs *regs)
                load_seg(0, &oldctx.gs_base,
                            &oldctx.gs_limit, &oldctx.gs_arbytes);
                oldctx.gs_sel = 0;
+               saved_rm_regs.vgs = regs->vgs;
        }
 
        /* initialize jump environment to warp back to protected mode */
@@ -880,16 +889,22 @@ real_mode(struct regs *regs)
                if (regs->uss >= HIGHMEM)
                        panic("%%ss 0x%lx higher than 1MB", regs->uss);
                regs->uss = address(regs, regs->uss, 0) >> 4;
+       } else {
+         regs->uss = saved_rm_regs.uss;
        }
        if (regs->vds != 0) {
                if (regs->vds >= HIGHMEM)
                        panic("%%ds 0x%lx higher than 1MB", regs->vds);
                regs->vds = address(regs, regs->vds, 0) >> 4;
+       } else {
+         regs->vds = saved_rm_regs.vds;
        }
        if (regs->ves != 0) {
                if (regs->ves >= HIGHMEM)
                        panic("%%es 0x%lx higher than 1MB", regs->ves);
                regs->ves = address(regs, regs->ves, 0) >> 4;
+       } else {
+         regs->ves = saved_rm_regs.ves;
        }
 
        /* this should get us into 16-bit mode */
@@ -971,6 +986,39 @@ jmpl(struct regs *regs, int prefix)
        } else if (mode == VM86_PROTECTED_TO_REAL) { /* jump to real mode */
                eip = (prefix & DATA32) ? fetch32(regs) : fetch16(regs);
                cs = fetch16(regs);
+
+               TRACE((regs, (regs->eip - n) + 1, "jmpl 0x%x:0x%x", cs, eip));
+
+                regs->cs = cs;
+                regs->eip = eip;
+               set_mode(regs, VM86_REAL);
+       } else
+               panic("jmpl");
+}
+
+static void
+jmpl_indirect(struct regs *regs, int prefix, unsigned modrm)
+{
+       unsigned n = regs->eip;
+       unsigned cs, eip;
+       unsigned addr;
+
+       addr  = operand(prefix, regs, modrm);
+
+       if (mode == VM86_REAL_TO_PROTECTED) { /* jump to protected mode */
+               eip = (prefix & DATA32) ? read32(addr) : read16(addr);
+               addr += (prefix & DATA32) ? 4 : 2;
+               cs = read16(addr);
+
+               TRACE((regs, (regs->eip - n) + 1, "jmpl 0x%x:0x%x", cs, eip));
+
+                regs->cs = cs;
+                regs->eip = eip;
+               set_mode(regs, VM86_PROTECTED);
+       } else if (mode == VM86_PROTECTED_TO_REAL) { /* jump to real mode */
+               eip = (prefix & DATA32) ? read32(addr) : read16(addr);
+               addr += (prefix & DATA32) ? 4 : 2;
+               cs = read16(addr);
 
                TRACE((regs, (regs->eip - n) + 1, "jmpl 0x%x:0x%x", cs, eip));
 
@@ -1306,6 +1354,23 @@ opcode(struct regs *regs)
                        }
                        goto invalid;
 
+               case 0xFF: /* jmpl (indirect) */
+                       if ((mode == VM86_REAL_TO_PROTECTED) ||
+                           (mode == VM86_PROTECTED_TO_REAL)) {
+                               unsigned modrm = fetch8(regs);
+                               
+                               switch((modrm >> 3) & 7) {
+                               case 5:
+                                 jmpl_indirect(regs, prefix, modrm);
+                                 return OPC_INVALID;
+
+                               default:
+                                 break;
+                               }
+
+                       }
+                       goto invalid;
+
                case 0xEB: /* short jump */
                        if ((mode == VM86_REAL_TO_PROTECTED) ||
                            (mode == VM86_PROTECTED_TO_REAL)) {
diff -r b8f6089cbce3 -r e74c47d073ee tools/ioemu/hw/cirrus_vga.c
--- a/tools/ioemu/hw/cirrus_vga.c       Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/ioemu/hw/cirrus_vga.c       Tue Jun 13 12:12:24 2006 -0600
@@ -1191,17 +1191,6 @@ cirrus_hook_write_sr(CirrusVGAState * s,
        s->hw_cursor_y = (reg_value << 3) | (reg_index >> 5);
        break;
     case 0x07:                 // Extended Sequencer Mode
-       /* Win2K seems to assume that the VRAM is set to 0xff
-        *   whenever VGA/SVGA mode changes 
-        */
-       if ((s->sr[0x07] ^ reg_value) & CIRRUS_SR7_BPP_SVGA)
-           memset(s->vram_ptr, 0xff, s->real_vram_size);
-       s->sr[0x07] = reg_value;
-#ifdef DEBUG_CIRRUS 
-       printf("cirrus: handled outport sr_index %02x, sr_value %02x\n",
-              reg_index, reg_value);
-#endif
-       break;
     case 0x08:                 // EEPROM Control
     case 0x09:                 // Scratch Register 0
     case 0x0a:                 // Scratch Register 1
@@ -2460,10 +2449,9 @@ static CPUWriteMemoryFunc *cirrus_linear
 };
 
 extern FILE *logfile;
-#if defined(__i386__) || defined (__x86_64__)
 static void * set_vram_mapping(unsigned long begin, unsigned long end)
 {
-    unsigned long * extent_start = NULL;
+    xen_pfn_t *extent_start = NULL;
     unsigned long nr_extents;
     void *vram_pointer = NULL;
     int i;
@@ -2474,14 +2462,14 @@ static void * set_vram_mapping(unsigned 
     end = (end + TARGET_PAGE_SIZE -1 ) & TARGET_PAGE_MASK;
     nr_extents = (end - begin) >> TARGET_PAGE_BITS;
 
-    extent_start = malloc(sizeof(unsigned long) * nr_extents );
+    extent_start = malloc(sizeof(xen_pfn_t) * nr_extents );
     if (extent_start == NULL)
     {
         fprintf(stderr, "Failed malloc on set_vram_mapping\n");
         return NULL;
     }
 
-    memset(extent_start, 0, sizeof(unsigned long) * nr_extents);
+    memset(extent_start, 0, sizeof(xen_pfn_t) * nr_extents);
 
     for (i = 0; i < nr_extents; i++)
     {
@@ -2509,7 +2497,7 @@ static void * set_vram_mapping(unsigned 
 
 static int unset_vram_mapping(unsigned long begin, unsigned long end)
 {
-    unsigned long * extent_start = NULL;
+    xen_pfn_t *extent_start = NULL;
     unsigned long nr_extents;
     int i;
 
@@ -2520,7 +2508,7 @@ static int unset_vram_mapping(unsigned l
     end = (end + TARGET_PAGE_SIZE -1 ) & TARGET_PAGE_MASK;
     nr_extents = (end - begin) >> TARGET_PAGE_BITS;
 
-    extent_start = malloc(sizeof(unsigned long) * nr_extents );
+    extent_start = malloc(sizeof(xen_pfn_t) * nr_extents );
 
     if (extent_start == NULL)
     {
@@ -2528,7 +2516,7 @@ static int unset_vram_mapping(unsigned l
         return -1;
     }
 
-    memset(extent_start, 0, sizeof(unsigned long) * nr_extents);
+    memset(extent_start, 0, sizeof(xen_pfn_t) * nr_extents);
 
     for (i = 0; i < nr_extents; i++)
         extent_start[i] = (begin + (i * TARGET_PAGE_SIZE)) >> TARGET_PAGE_BITS;
@@ -2540,10 +2528,6 @@ static int unset_vram_mapping(unsigned l
     return 0;
 }
 
-#elif defined(__ia64__)
-static void * set_vram_mapping(unsigned long addr, unsigned long end) {}
-static int unset_vram_mapping(unsigned long addr, unsigned long end) {}
-#endif
 extern int vga_accelerate;
 
 /* Compute the memory access functions */
diff -r b8f6089cbce3 -r e74c47d073ee tools/ioemu/hw/pc.c
--- a/tools/ioemu/hw/pc.c       Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/ioemu/hw/pc.c       Tue Jun 13 12:12:24 2006 -0600
@@ -40,6 +40,7 @@ int dummy_refresh_clock;
 int dummy_refresh_clock;
 static fdctrl_t *floppy_controller;
 static RTCState *rtc_state;
+static USBPort *usb_root_ports[2];
 
 static void ioport80_write(void *opaque, uint32_t addr, uint32_t data)
 {
@@ -537,8 +538,11 @@ void pc_init(uint64_t ram_size, int vga_
     for(i = 0; i < MAX_SERIAL_PORTS; i++) {
         if (serial_hds[i]) {
             sp = serial_init(serial_io[i], serial_irq[i], serial_hds[i]);
-            if (i == SUMMA_PORT)
+            if (i == serial_summa_port) {
                summa_init(sp, serial_hds[i]);
+               fprintf(stderr, "Serial port %d (COM%d) initialized for 
Summagraphics\n",
+                       i, i+1);
+           }
         }
     }
 
@@ -581,6 +585,11 @@ void pc_init(uint64_t ram_size, int vga_
     cmos_init(ram_size, boot_device, bs_table, timeoffset);
     acpi_init(0x8000);
 
+    if (pci_enabled && usb_enabled) {
+       usb_uhci_init(pci_bus, usb_root_ports);
+       usb_attach(usb_root_ports[0], vm_usb_hub);
+    }
+
     /* must be done after all PCI devices are instanciated */
     /* XXX: should be done in the Bochs BIOS */
     if (pci_enabled) {
diff -r b8f6089cbce3 -r e74c47d073ee tools/ioemu/hw/pckbd.c
--- a/tools/ioemu/hw/pckbd.c    Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/ioemu/hw/pckbd.c    Tue Jun 13 12:12:24 2006 -0600
@@ -118,6 +118,9 @@
 #define SUMMA_MAXX     (16000 - 1)
 #define SUMMA_MAXY     (16000 - 1)
 
+#define MAX_ABSX       0x7fff
+#define MAX_ABSY       0x7fff
+
 typedef struct {
     uint8_t aux[KBD_QUEUE_SIZE];
     uint8_t data[KBD_QUEUE_SIZE];
@@ -149,8 +152,6 @@ typedef struct KBDState {
     uint8_t mouse_wrap;
     uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
     uint8_t mouse_detect_state;
-    int mouse_x;  /* absolute coordinates (for mousepad) */
-    int mouse_y;
     int mouse_dx; /* current values, needed for 'poll' mode */
     int mouse_dy;
     int mouse_dz;
@@ -422,7 +423,7 @@ static void kbd_write_keyboard(KBDState 
 
 int mouse_maxx, mouse_maxy;
 
-static int kbd_mouse_send_packet(KBDState *s)
+static void kbd_mouse_send_packet(KBDState *s)
 {
     unsigned int b;
     int dx1, dy1, dz1;
@@ -430,100 +431,63 @@ static int kbd_mouse_send_packet(KBDStat
     dx1 = s->mouse_dx;
     dy1 = s->mouse_dy;
     dz1 = s->mouse_dz;
+    /* XXX: increase range to 8 bits ? */
+    if (dx1 > 127)
+        dx1 = 127;
+    else if (dx1 < -127)
+        dx1 = -127;
+    if (dy1 > 127)
+        dy1 = 127;
+    else if (dy1 < -127)
+        dy1 = -127;
+    b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
+    kbd_queue(s, b, 1);
+    kbd_queue(s, dx1 & 0xff, 1);
+    kbd_queue(s, dy1 & 0xff, 1);
+    /* extra byte for IMPS/2 or IMEX */
     switch(s->mouse_type) {
-  
-    case TABLET:        /* Summagraphics pen tablet */
-       if (SummaState.report_mode == MODE_STREAM) {
-           dx1 = s->mouse_x;
-           dy1 = s->mouse_y;
-           if (SummaState.origin == ORIGIN_LOWER_LEFT)
-               dy1 = mouse_maxy - dy1;
-           dx1 = ((dx1 * SUMMA_MAXX) / mouse_maxx) + SUMMA_BORDER;
-           dy1 = ((dy1 * SUMMA_MAXY) / mouse_maxy) + SUMMA_BORDER;
-           ser_queue(s->serial, 0x80 | (s->mouse_buttons & 7));
-           ser_queue(s->serial, dx1 & 0x7f);
-           ser_queue(s->serial, dx1 >> 7);
-           ser_queue(s->serial, dy1 & 0x7f);
-           ser_queue(s->serial, dy1 >> 7);
-       }
-       s->mouse_dx = 0; 
-       s->mouse_dy = 0;
-       s->mouse_dz = 0;
-       return 0;
-
-    default:   /* PS/2 style mice */
-       /* XXX: increase range to 8 bits ? */
-       if (dx1 > 127)
-           dx1 = 127;
-       else if (dx1 < -127)
-           dx1 = -127;
-       if (dy1 > 127)
-           dy1 = 127;
-       else if (dy1 < -127)
-           dy1 = -127;
-       b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 
0x07);
-       kbd_queue(s, b, 1);
-       kbd_queue(s, dx1 & 0xff, 1);
-       kbd_queue(s, dy1 & 0xff, 1);
-       /* extra byte for IMPS/2 or IMEX */
-       switch(s->mouse_type) {
-
-       default:
-           break;
-
-       case IMPS2:
-           if (dz1 > 127)
-               dz1 = 127;
-           else if (dz1 < -127)
-               dz1 = -127;
-           kbd_queue(s, dz1 & 0xff, 1);
-           break;
-
-       case IMEX:
-           if (dz1 > 7)
-               dz1 = 7;
-           else if (dz1 < -7)
-               dz1 = -7;
-           b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
-           kbd_queue(s, b, 1);
-           break;
-       }
-
-       /* update deltas */
-       s->mouse_dx -= dx1;
-       s->mouse_dy -= dy1;
-       s->mouse_dz -= dz1;
-       return s->mouse_dx || s->mouse_dy || s->mouse_dz;
-
-    }
-}
-
-static void pc_kbd_mouse_event(void *opaque, 
-                               int dx, int dy, int dz, int buttons_state,
-                              int x, int y)
+    default:
+        break;
+    case IMPS2:
+        if (dz1 > 127)
+            dz1 = 127;
+        else if (dz1 < -127)
+                dz1 = -127;
+        kbd_queue(s, dz1 & 0xff, 1);
+        break;
+    case IMEX:
+        if (dz1 > 7)
+            dz1 = 7;
+        else if (dz1 < -7)
+            dz1 = -7;
+        b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
+        kbd_queue(s, b, 1);
+        break;
+    }
+
+    /* update deltas */
+    s->mouse_dx -= dx1;
+    s->mouse_dy -= dy1;
+    s->mouse_dz -= dz1;
+}
+
+static void summa_mouse_event(void *opaque, int x, int y, int z, int 
buttons_state)
 {
     KBDState *s = opaque;
 
-    /* check if deltas are recorded when disabled */
-    if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
-        return;
-
-    s->mouse_x = x;
-    s->mouse_y = y;
-    s->mouse_dx += dx;
-    s->mouse_dy -= dy;
-    s->mouse_dz += dz;
-    /* XXX: SDL sometimes generates nul events: we delete them */
-    if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0 &&
-        s->mouse_buttons == buttons_state)
-       return;
-    s->mouse_buttons = buttons_state;
-    
-    if (!(s->mouse_status & MOUSE_STATUS_REMOTE) &&
-        (s->queue.count < (KBD_QUEUE_SIZE - 16))) {
-               while (kbd_mouse_send_packet(s))
-                   ;
-    }
+    if (SummaState.report_mode == MODE_STREAM) {
+       if (SummaState.origin == ORIGIN_LOWER_LEFT)
+           y = mouse_maxy - y;
+       x = ((x * SUMMA_MAXX) / MAX_ABSX) + SUMMA_BORDER;
+       y = ((y * SUMMA_MAXY) / MAX_ABSY) + SUMMA_BORDER;
+fprintf(stderr, "summa_mouse_event: x, y - %d, %d\n", x, y);
+       ser_queue(s->serial, 0x80 | (buttons_state & 7));
+       ser_queue(s->serial, x & 0x7f);
+       ser_queue(s->serial, x >> 7);
+       ser_queue(s->serial, y & 0x7f);
+       ser_queue(s->serial, y >> 7);
+    }
+    return;
 }
 
 static void summa(KBDState *s, uint8_t val)
@@ -564,6 +528,7 @@ static void summa(KBDState *s, uint8_t v
        s->mouse_status |= MOUSE_STATUS_ENABLED;
        SummaState.origin = ORIGIN_LOWER_LEFT;
        SummaState.report_mode = (val == 'B') ? MODE_POINT : MODE_STREAM_SWITCH;
+       qemu_add_mouse_event_handler(summa_mouse_event, s, 1);
        break;
 
     case 'z':  /* start of 2 byte command */
@@ -645,6 +610,36 @@ void summa_init(SerialState *serial, Cha
     chr->chr_write = summa_write;
     chr->opaque = (void *)&kbd_state;
     return;
+}
+
+static void pc_kbd_mouse_event(void *opaque, 
+                               int dx, int dy, int dz, int buttons_state)
+{
+    KBDState *s = opaque;
+
+    /* check if deltas are recorded when disabled */
+    if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
+        return;
+
+    s->mouse_dx += dx;
+    s->mouse_dy -= dy;
+    s->mouse_dz += dz;
+    /* XXX: SDL sometimes generates nul events: we delete them */
+    if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0 &&
+        s->mouse_buttons == buttons_state)
+       return;
+    s->mouse_buttons = buttons_state;
+    
+    if (!(s->mouse_status & MOUSE_STATUS_REMOTE) &&
+        (s->queue.count < (KBD_QUEUE_SIZE - 16))) {
+       for(;;) {
+           /* if not remote, send event. Multiple events are sent if
+              too big deltas */
+           kbd_mouse_send_packet(s);
+           if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
+               break;
+       }
+    }
 }
 
 static void kbd_write_mouse(KBDState *s, int val)
@@ -890,6 +885,6 @@ void kbd_init(void)
     register_ioport_write(0x64, 1, 1, kbd_write_command, s);
 
     qemu_add_kbd_event_handler(pc_kbd_put_keycode, s);
-    qemu_add_mouse_event_handler(pc_kbd_mouse_event, s);
+    qemu_add_mouse_event_handler(pc_kbd_mouse_event, s, 0);
     qemu_register_reset(kbd_reset, s);
 }
diff -r b8f6089cbce3 -r e74c47d073ee tools/ioemu/hw/vga.c
--- a/tools/ioemu/hw/vga.c      Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/ioemu/hw/vga.c      Tue Jun 13 12:12:24 2006 -0600
@@ -1995,6 +1995,7 @@ void vga_common_init(VGAState *s, Displa
     s->get_resolution = vga_get_resolution;
     /* XXX: currently needed for display */
     vga_state = s;
+    vga_bios_init(s);
 }
 
 
@@ -2082,7 +2083,6 @@ int vga_initialize(PCIBus *bus, DisplayS
 #endif
     }
 
-    vga_bios_init(s);
     return 0;
 }
 
diff -r b8f6089cbce3 -r e74c47d073ee tools/ioemu/monitor.c
--- a/tools/ioemu/monitor.c     Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/ioemu/monitor.c     Tue Jun 13 12:12:24 2006 -0600
@@ -492,6 +492,10 @@ static term_cmd_t term_cmds[] = {
       "", "quit the emulator" },
     { "sendkey", "s", do_send_key, 
       "keys", "send keys to the VM (e.g. 'sendkey ctrl-alt-f1')" },
+    { "usb_add", "s", do_usb_add,
+      "device", "add USB device (e.g. 'host:bus.addr' or 
'host:vendor_id:product_id')" },
+    { "usb_del", "s", do_usb_del,
+      "device", "remove USB device 'bus.addr'" },
     { NULL, NULL, }, 
 };
 
@@ -510,6 +514,10 @@ static term_cmd_t info_cmds[] = {
       "", "show i8259 (PIC) state", },
     { "pci", "", pci_info,
       "", "show PCI info", },
+    { "usb", "", usb_info,
+      "", "show guest USB devices", },
+    { "usbhost", "", usb_host_info,
+      "", "show host USB devices", },
     { "hvmiopage", "", sp_info,
       "", "show HVM device model shared page info", },
     { NULL, NULL, },
diff -r b8f6089cbce3 -r e74c47d073ee tools/ioemu/sdl.c
--- a/tools/ioemu/sdl.c Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/ioemu/sdl.c Tue Jun 13 12:12:24 2006 -0600
@@ -49,8 +49,12 @@ static int gui_fullscreen_initial_grab;
 static int gui_fullscreen_initial_grab;
 static int gui_grab_code = KMOD_LALT | KMOD_LCTRL;
 static uint8_t modifiers_state[256];
-
-SDL_PixelFormat* sdl_get_format() {
+static int width, height;
+static SDL_Cursor *sdl_cursor_normal;
+static SDL_Cursor *sdl_cursor_hidden;
+static int absolute_enabled = 0;
+
+SDL_PixelFormat* sdl_get_format(void) {
        return screen->format;
 }
 
@@ -69,6 +73,8 @@ static void sdl_resize(DisplayState *ds,
     flags |= SDL_RESIZABLE;
     if (gui_fullscreen)
         flags |= SDL_FULLSCREEN;
+    width = w;
+    height = h;
     screen = SDL_SetVideoMode(w, h, 0, flags);
     if (!screen) {
         fprintf(stderr, "Could not open SDL display\n");
@@ -368,9 +374,21 @@ static void sdl_update_caption(void)
     SDL_WM_SetCaption(buf, domain_name);
 }
 
+static void sdl_hide_cursor(void)
+{
+    SDL_SetCursor(sdl_cursor_hidden);
+}
+
+static void sdl_show_cursor(void)
+{
+    if (!kbd_mouse_is_absolute()) {
+       SDL_SetCursor(sdl_cursor_normal);
+    }
+}
+
 static void sdl_grab_start(void)
 {
-    SDL_ShowCursor(0);
+    sdl_hide_cursor();
     SDL_WM_GrabInput(SDL_GRAB_ON);
     /* dummy read to avoid moving the mouse */
     SDL_GetRelativeMouseState(NULL, NULL);
@@ -381,6 +399,7 @@ static void sdl_grab_end(void)
 static void sdl_grab_end(void)
 {
     SDL_WM_GrabInput(SDL_GRAB_OFF);
+    sdl_show_cursor();
     SDL_ShowCursor(1);
     gui_grab = 0;
     sdl_update_caption();
@@ -397,6 +416,21 @@ static void sdl_send_mouse_event(void)
         buttons |= MOUSE_EVENT_RBUTTON;
     if (state & SDL_BUTTON(SDL_BUTTON_MIDDLE))
         buttons |= MOUSE_EVENT_MBUTTON;
+
+    if (kbd_mouse_is_absolute()) {
+       if (!absolute_enabled) {
+           sdl_hide_cursor();
+           if (gui_grab) {
+               sdl_grab_end();
+           }
+           absolute_enabled = 1;
+       }
+
+       SDL_GetMouseState(&dx, &dy);
+       dx = dx * 0x7FFF / width;
+       dy = dy * 0x7FFF / height;
+    }
+
     /* XXX: test wheel */
     dz = 0;
 #ifdef SDL_BUTTON_WHEELUP
@@ -405,7 +439,7 @@ static void sdl_send_mouse_event(void)
     if (state & SDL_BUTTON(SDL_BUTTON_WHEELDOWN))
         dz++;
 #endif
-    kbd_mouse_event(dx, dy, dz, buttons, 0, 0);
+    kbd_mouse_event(dx, dy, dz, buttons);
 }
 
 static void toggle_full_screen(DisplayState *ds)
@@ -571,6 +605,7 @@ void sdl_display_init(DisplayState *ds, 
 void sdl_display_init(DisplayState *ds, int full_screen)
 {
     int flags;
+    uint8_t data = 0;
 
     if(keyboard_layout)
            kbd_layout=init_keyboard_layout(keyboard_layout);
@@ -597,6 +632,9 @@ void sdl_display_init(DisplayState *ds, 
     SDL_EnableUNICODE(1);
     gui_grab = 0;
 
+    sdl_cursor_hidden = SDL_CreateCursor(&data, &data, 8, 1, 0, 0);
+    sdl_cursor_normal = SDL_GetCursor();
+
     atexit(sdl_cleanup);
     if (full_screen) {
         gui_fullscreen = 1;
diff -r b8f6089cbce3 -r e74c47d073ee tools/ioemu/target-i386-dm/Makefile
--- a/tools/ioemu/target-i386-dm/Makefile       Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/ioemu/target-i386-dm/Makefile       Tue Jun 13 12:12:24 2006 -0600
@@ -274,6 +274,9 @@ audio.o fmodaudio.o: DEFINES := -I$(CONF
 audio.o fmodaudio.o: DEFINES := -I$(CONFIG_FMOD_INC) $(DEFINES)
 LIBS += $(CONFIG_FMOD_LIB)
 endif
+
+# USB layer
+VL_OBJS+= usb.o usb-hub.o usb-uhci.o usb-linux.o usb-hid.o
 
 # Hardware support
 VL_OBJS+= ide.o ne2000.o pckbd.o vga.o dma.o
diff -r b8f6089cbce3 -r e74c47d073ee tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/ioemu/vl.c  Tue Jun 13 12:12:24 2006 -0600
@@ -144,8 +144,12 @@ int graphic_depth = 15;
 int graphic_depth = 15;
 int full_screen = 0;
 int repeat_key = 1;
+int usb_enabled = 0;
+USBPort *vm_usb_ports[MAX_VM_USB_PORTS];
+USBDevice *vm_usb_hub;
 TextConsole *vga_console;
 CharDriverState *serial_hds[MAX_SERIAL_PORTS];
+int serial_summa_port = -1;
 int xc_handle;
 time_t timeoffset = 0;
 
@@ -437,6 +441,7 @@ static void *qemu_put_kbd_event_opaque;
 static void *qemu_put_kbd_event_opaque;
 static QEMUPutMouseEvent *qemu_put_mouse_event;
 static void *qemu_put_mouse_event_opaque;
+static int qemu_put_mouse_event_absolute;
 
 void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
 {
@@ -444,10 +449,11 @@ void qemu_add_kbd_event_handler(QEMUPutK
     qemu_put_kbd_event = func;
 }
 
-void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque)
+void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque, int 
absolute)
 {
     qemu_put_mouse_event_opaque = opaque;
     qemu_put_mouse_event = func;
+    qemu_put_mouse_event_absolute = absolute;
 }
 
 void kbd_put_keycode(int keycode)
@@ -457,12 +463,17 @@ void kbd_put_keycode(int keycode)
     }
 }
 
-void kbd_mouse_event(int dx, int dy, int dz, int buttons_state, int x, int y)
+void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
 {
     if (qemu_put_mouse_event) {
         qemu_put_mouse_event(qemu_put_mouse_event_opaque,
-                             dx, dy, dz, buttons_state, x, y);
-    }
+                             dx, dy, dz, buttons_state);
+    }
+}
+
+int kbd_mouse_is_absolute(void)
+{
+    return qemu_put_mouse_event_absolute;
 }
 
 /***********************************************************/
@@ -1643,6 +1654,121 @@ static int net_fd_init(NetDriverState *n
 }
 
 #endif /* !_WIN32 */
+ 
+/***********************************************************/
+/* USB devices */
+
+static int usb_device_add(const char *devname)
+{
+    const char *p;
+    USBDevice *dev;
+    int i;
+
+    if (!vm_usb_hub)
+        return -1;
+    for(i = 0;i < MAX_VM_USB_PORTS; i++) {
+        if (!vm_usb_ports[i]->dev)
+            break;
+    }
+    if (i == MAX_VM_USB_PORTS)
+        return -1;
+
+    if (strstart(devname, "host:", &p)) {
+        dev = usb_host_device_open(p);
+        if (!dev)
+            return -1;
+    } else if (!strcmp(devname, "mouse")) {
+        dev = usb_mouse_init();
+        if (!dev)
+            return -1;
+    } else if (!strcmp(devname, "tablet")) {
+       dev = usb_tablet_init();
+       if (!dev)
+           return -1;
+    } else {
+        return -1;
+    }
+    usb_attach(vm_usb_ports[i], dev);
+    return 0;
+}
+
+static int usb_device_del(const char *devname)
+{
+    USBDevice *dev;
+    int bus_num, addr, i;
+    const char *p;
+
+    if (!vm_usb_hub)
+        return -1;
+
+    p = strchr(devname, '.');
+    if (!p) 
+        return -1;
+    bus_num = strtoul(devname, NULL, 0);
+    addr = strtoul(p + 1, NULL, 0);
+    if (bus_num != 0)
+        return -1;
+    for(i = 0;i < MAX_VM_USB_PORTS; i++) {
+        dev = vm_usb_ports[i]->dev;
+        if (dev && dev->addr == addr)
+            break;
+    }
+    if (i == MAX_VM_USB_PORTS)
+        return -1;
+    usb_attach(vm_usb_ports[i], NULL);
+    return 0;
+}
+
+void do_usb_add(const char *devname)
+{
+    int ret;
+    ret = usb_device_add(devname);
+    if (ret < 0) 
+        term_printf("Could not add USB device '%s'\n", devname);
+}
+
+void do_usb_del(const char *devname)
+{
+    int ret;
+    ret = usb_device_del(devname);
+    if (ret < 0) 
+        term_printf("Could not remove USB device '%s'\n", devname);
+}
+
+void usb_info(void)
+{
+    USBDevice *dev;
+    int i;
+    const char *speed_str;
+
+    if (!vm_usb_hub) {
+        term_printf("USB support not enabled\n");
+        return;
+    }
+
+    for(i = 0; i < MAX_VM_USB_PORTS; i++) {
+        dev = vm_usb_ports[i]->dev;
+        if (dev) {
+            term_printf("Hub port %d:\n", i);
+            switch(dev->speed) {
+            case USB_SPEED_LOW: 
+                speed_str = "1.5"; 
+                break;
+            case USB_SPEED_FULL: 
+                speed_str = "12"; 
+                break;
+            case USB_SPEED_HIGH: 
+                speed_str = "480"; 
+                break;
+            default:
+                speed_str = "?"; 
+                break;
+            }
+            term_printf("  Device %d.%d, speed %s Mb/s\n", 
+                        0, dev->addr, speed_str);
+        }
+    }
+}
 
 /***********************************************************/
 /* dumb display */
@@ -2213,6 +2339,8 @@ void help(void)
            "-enable-audio   enable audio support\n"
            "-localtime      set the real time clock to local time 
[default=utc]\n"
            "-full-screen    start in full screen\n"
+           "-usb            enable the USB driver (will be the default soon)\n"
+           "-usbdevice name add the host or guest USB device 'name'\n"
 #ifdef TARGET_PPC
            "-prep           Simulate a PREP system (default is PowerMAC)\n"
            "-g WxH[xDEPTH]  Set the initial VGA graphic mode\n"
@@ -2354,6 +2482,8 @@ enum {
     QEMU_OPTION_full_screen,
     QEMU_OPTION_vgaacc,
     QEMU_OPTION_repeatkey,
+    QEMU_OPTION_usb,
+    QEMU_OPTION_usbdevice,
 };
 
 typedef struct QEMUOption {
@@ -2427,8 +2557,10 @@ const QEMUOption qemu_options[] = {
     { "serial", 1, QEMU_OPTION_serial },
     { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
     { "full-screen", 0, QEMU_OPTION_full_screen },
+    { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
 
     /* temporary options */
+    { "usb", 0, QEMU_OPTION_usb },
     { "pci", 0, QEMU_OPTION_pci },
     { "nic-ne2000", 0, QEMU_OPTION_nic_ne2000 },
     { "cirrusvga", 0, QEMU_OPTION_cirrusvga },
@@ -2457,7 +2589,7 @@ int unset_mm_mapping(int xc_handle,
                      uint32_t domid,
                      unsigned long nr_pages,
                      unsigned int address_bits,
-                     unsigned long *extent_start)
+                     xen_pfn_t *extent_start)
 {
     int err = 0;
     xc_dominfo_t info;
@@ -2490,7 +2622,7 @@ int set_mm_mapping(int xc_handle,
                     uint32_t domid,
                     unsigned long nr_pages,
                     unsigned int address_bits,
-                    unsigned long *extent_start)
+                    xen_pfn_t *extent_start)
 {
     xc_dominfo_t info;
     int err = 0;
@@ -2498,7 +2630,7 @@ int set_mm_mapping(int xc_handle,
     xc_domain_getinfo(xc_handle, domid, 1, &info);
 
     if ( xc_domain_setmaxmem(xc_handle, domid,
-                             (info.nr_pages + nr_pages) * PAGE_SIZE/1024) != 0)
+                             info.max_memkb + nr_pages * PAGE_SIZE/1024) !=0)
     {
         fprintf(logfile, "set maxmem returned error %d\n", errno);
         return -1;
@@ -2554,9 +2686,12 @@ int main(int argc, char **argv)
     char monitor_device[128];
     char serial_devices[MAX_SERIAL_PORTS][128];
     int serial_device_index;
+    char usb_devices[MAX_VM_USB_PORTS][128];
+    int usb_devices_index;
     char qemu_dm_logfilename[64];
     const char *loadvm = NULL;
-    unsigned long nr_pages, *page_array;
+    unsigned long nr_pages;
+    xen_pfn_t *page_array;
     extern void *shared_page;
 
 #if !defined(CONFIG_SOFTMMU)
@@ -2588,11 +2723,12 @@ int main(int argc, char **argv)
     pstrcpy(monitor_device, sizeof(monitor_device), "vc");
 
     pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
-    pstrcpy(serial_devices[1], sizeof(serial_devices[1]), "null");
-    for(i = 2; i < MAX_SERIAL_PORTS; i++)
+    serial_summa_port = -1;
+    for(i = 1; i < MAX_SERIAL_PORTS; i++)
         serial_devices[i][0] = '\0';
     serial_device_index = 0;
 
+    usb_devices_index = 0;
     nb_tun_fds = 0;
     net_if_type = -1;
     nb_nics = 1;
@@ -2937,6 +3073,20 @@ int main(int argc, char **argv)
             case QEMU_OPTION_full_screen:
                 full_screen = 1;
                 break;
+            case QEMU_OPTION_usb:
+                usb_enabled = 1;
+                break;
+            case QEMU_OPTION_usbdevice:
+                usb_enabled = 1;
+                if (usb_devices_index >= MAX_VM_USB_PORTS) {
+                    fprintf(stderr, "Too many USB devices\n");
+                    exit(1);
+                }
+                pstrcpy(usb_devices[usb_devices_index],
+                        sizeof(usb_devices[usb_devices_index]),
+                        optarg);
+                usb_devices_index++;
+                break;
             case QEMU_OPTION_domainname:
                 strncat(domain_name, optarg, sizeof(domain_name) - 20);
                 break;
@@ -3022,8 +3172,8 @@ int main(int argc, char **argv)
 
     xc_handle = xc_interface_open();
 
-    if ( (page_array = (unsigned long *)
-                        malloc(nr_pages * sizeof(unsigned long))) == NULL)
+    if ( (page_array = (xen_pfn_t *)
+                        malloc(nr_pages * sizeof(xen_pfn_t))) == NULL)
     {
         fprintf(logfile, "malloc returned error %d\n", errno);
         exit(-1);
@@ -3078,8 +3228,8 @@ int main(int argc, char **argv)
                                        page_array[0]);
 #endif
 
-    fprintf(logfile, "shared page at pfn:%lx, mfn: %lx\n", (nr_pages-1),
-           (page_array[nr_pages - 1]));
+    fprintf(logfile, "shared page at pfn:%lx, mfn: %"PRIx64"\n", (nr_pages-1),
+           (uint64_t)(page_array[nr_pages - 1]));
 
     /* we always create the cdrom drive, even if no disk is there */
     bdrv_init();
@@ -3137,6 +3287,17 @@ int main(int argc, char **argv)
         }
     }
 
+    /* init USB devices */
+    if (usb_enabled) {
+        vm_usb_hub = usb_hub_init(vm_usb_ports, MAX_VM_USB_PORTS);
+        for(i = 0; i < usb_devices_index; i++) {
+            if (usb_device_add(usb_devices[i]) < 0) {
+                fprintf(stderr, "Warning: could not add USB device %s\n",
+                        usb_devices[i]);
+            }
+        }
+    }
+
     /* init CPU state */
     env = cpu_init();
     global_env = env;
@@ -3172,6 +3333,20 @@ int main(int argc, char **argv)
         exit(1);
     }
     monitor_init(monitor_hd, !nographic);
+
+    /* Find which port should be the Summagraphics port */
+    /* It's the first unspecified serial line. Note that COM1 is set */
+    /* by default, so the Summagraphics port would be COM2 or higher */
+
+    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
+      if (serial_devices[i][0] != '\0')
+       continue;
+      serial_summa_port = i;
+      pstrcpy(serial_devices[serial_summa_port], sizeof(serial_devices[0]), 
"null");
+      break;
+    }
+
+    /* Now, open the ports */
 
     for(i = 0; i < MAX_SERIAL_PORTS; i++) {
         if (serial_devices[i][0] != '\0') {
diff -r b8f6089cbce3 -r e74c47d073ee tools/ioemu/vl.h
--- a/tools/ioemu/vl.h  Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/ioemu/vl.h  Tue Jun 13 12:12:24 2006 -0600
@@ -154,13 +154,14 @@ extern int graphic_depth;
 #define MOUSE_EVENT_MBUTTON 0x04
 
 typedef void QEMUPutKBDEvent(void *opaque, int keycode);
-typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int 
buttons_state, int x, int y);
+typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int 
buttons_state);
 
 void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque);
-void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque);
+void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque, int 
absolute);
 
 void kbd_put_keycode(int keycode);
-void kbd_mouse_event(int dx, int dy, int dz, int buttons_state, int x, int y);
+void kbd_mouse_event(int dx, int dy, int dz, int buttons_state);
+int kbd_mouse_is_absolute(void);
 
 /* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
    constants) */
@@ -238,9 +239,9 @@ void console_select(unsigned int index);
 /* serial ports */
 
 #define MAX_SERIAL_PORTS 4
-#define SUMMA_PORT     1
 
 extern CharDriverState *serial_hds[MAX_SERIAL_PORTS];
+extern int serial_summa_port;
 
 /* network redirectors support */
 
@@ -633,6 +634,7 @@ void kbd_init(void);
 void kbd_init(void);
 extern const char* keyboard_layout;
 extern int repeat_key;
+extern int usb_enabled;
 
 /* mc146818rtc.c */
 
@@ -792,6 +794,19 @@ void adb_mouse_init(ADBBusState *bus);
 
 /* cuda.c */
 
+#include "hw/usb.h"
+
+/* usb ports of the VM */
+
+#define MAX_VM_USB_PORTS 8
+
+extern USBPort *vm_usb_ports[MAX_VM_USB_PORTS];
+extern USBDevice *vm_usb_hub;
+
+void do_usb_add(const char *devname);
+void do_usb_del(const char *devname);
+void usb_info(void);
+
 extern ADBBusState adb_bus;
 int cuda_init(openpic_t *openpic, int irq);
 
diff -r b8f6089cbce3 -r e74c47d073ee tools/ioemu/vnc.c
--- a/tools/ioemu/vnc.c Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/ioemu/vnc.c Tue Jun 13 12:12:24 2006 -0600
@@ -138,9 +138,16 @@ static void init_mouse(int max_x,int max
 }
 
 static void mouse_refresh() {
+       static int last_x = -1;
+       static int last_y = -1;
+       static int last_z = -1;
+       static int last_b = -1;
        int dx=0,dy=0,dz=new_mouse_z;
        static int counter=1;
 
+       if (new_mouse_x == last_x && new_mouse_y == last_y &&
+           new_mouse_z == last_z && new_mouse_buttons == last_b)
+               return;
        /*
         *  Simulate lifting the mouse by pressing left <ctl><alt> together
         *  e.g. don't send mouse events.
@@ -148,27 +155,40 @@ static void mouse_refresh() {
        if (ctl_keys == 3) {
                mouse_x = new_mouse_x;
                mouse_y = new_mouse_y;
+               last_x = new_mouse_x;
+               last_y = new_mouse_y;
+               last_z = new_mouse_z;
+               last_b = new_mouse_buttons;
                return;
        }
        counter++;
-       if(!mouse_magic->calibration && counter>=2) { counter=0; return; }
-
-       dx=new_mouse_x-mouse_x;
-       dy=new_mouse_y-mouse_y;
-
-       if(mouse_magic->sonic_wall_is_orthogonal) {
-               if(abs(dx)>=mouse_magic->sonic_wall_x) { dx/=2; mouse_x+=dx; }
-               if(abs(dy)>=mouse_magic->sonic_wall_y) { dy/=2; mouse_y+=dy; }
+       //fprintf(stderr,"sending mouse event %d,%d\n",dx,dy);
+       if (kbd_mouse_is_absolute()) {
+               kbd_mouse_event(new_mouse_x * 0x7FFF / screen->width,
+                               new_mouse_y * 0x7FFF / screen->height, dz, 
new_mouse_buttons);
        } else {
-               if(abs(dx)>=mouse_magic->sonic_wall_x || 
abs(dy)>=mouse_magic->sonic_wall_y) {
-                       dx/=2; mouse_x+=dx;
-                       dy/=2; mouse_y+=dy;
-               }
-       }
-       //fprintf(stderr,"sending mouse event %d,%d\n",dx,dy);
-       kbd_mouse_event(dx,dy,dz,new_mouse_buttons,new_mouse_x,new_mouse_y);
-       mouse_x+=dx;
-       mouse_y+=dy;
+               if(!mouse_magic->calibration && counter>=2) { counter=0; 
return; }
+
+               dx=new_mouse_x-last_x;
+               dy=new_mouse_y-last_y;
+
+               if(mouse_magic->sonic_wall_is_orthogonal) {
+                       if(abs(dx)>=mouse_magic->sonic_wall_x) { dx/=2; 
mouse_x+=dx; }
+                       if(abs(dy)>=mouse_magic->sonic_wall_y) { dy/=2; 
mouse_y+=dy; }
+               } else {
+                       if(abs(dx)>=mouse_magic->sonic_wall_x || 
abs(dy)>=mouse_magic->sonic_wall_y) {
+                               dx/=2; mouse_x+=dx;
+                               dy/=2; mouse_y+=dy;
+                       }
+               }
+               if (last_x != -1)
+                       kbd_mouse_event(dx,dy,dz,new_mouse_buttons);
+
+       }
+       last_x = new_mouse_x;
+       last_y = new_mouse_y;
+       last_z = new_mouse_z;
+       last_b = new_mouse_buttons;
                
        updates_since_mouse=0;
 }
@@ -250,7 +270,7 @@ static void mouse_calibration_refresh() 
        
        if(calibration_step==0) {
                x=0; y=1;
-               kbd_mouse_event(0,-1,0,0,x,y);
+               kbd_mouse_event(0,-1,0,0);
                calibration_step++;
        } else if(calibration_step==1) {
                // find out the initial position of the cursor
@@ -282,7 +302,7 @@ static void mouse_calibration_refresh() 
                } else {
                        y++;
 move_calibrate:
-                       kbd_mouse_event(-x,-y,0,0,x,y);
+                       kbd_mouse_event(-x,-y,0,0);
                        before_update=last_update;
                }
        } else if(calibration_step==3) {
diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_core.c
--- a/tools/libxc/xc_core.c     Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/libxc/xc_core.c     Tue Jun 13 12:12:24 2006 -0600
@@ -28,7 +28,7 @@ xc_domain_dumpcore_via_callback(int xc_h
                                 dumpcore_rtn_t dump_rtn)
 {
     unsigned long nr_pages;
-    unsigned long *page_array = NULL;
+    xen_pfn_t *page_array = NULL;
     xc_dominfo_t info;
     int i, nr_vcpus = 0;
     char *dump_mem, *dump_mem_start = NULL;
@@ -70,7 +70,7 @@ xc_domain_dumpcore_via_callback(int xc_h
         sizeof(vcpu_guest_context_t)*nr_vcpus;
     dummy_len = (sizeof(struct xc_core_header) +
                  (sizeof(vcpu_guest_context_t) * nr_vcpus) +
-                 (nr_pages * sizeof(unsigned long)));
+                 (nr_pages * sizeof(xen_pfn_t)));
     header.xch_pages_offset = round_pgup(dummy_len);
 
     sts = dump_rtn(args, (char *)&header, sizeof(struct xc_core_header));
@@ -81,17 +81,17 @@ xc_domain_dumpcore_via_callback(int xc_h
     if ( sts != 0 )
         goto error_out;
 
-    if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
+    if ( (page_array = malloc(nr_pages * sizeof(xen_pfn_t))) == NULL )
     {
-        printf("Could not allocate memory\n");
+        IPRINTF("Could not allocate memory\n");
         goto error_out;
     }
     if ( xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages )
     {
-        printf("Could not get the page frame list\n");
+        IPRINTF("Could not get the page frame list\n");
         goto error_out;
     }
-    sts = dump_rtn(args, (char *)page_array, nr_pages * sizeof(unsigned long));
+    sts = dump_rtn(args, (char *)page_array, nr_pages * sizeof(xen_pfn_t));
     if ( sts != 0 )
         goto error_out;
 
diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c   Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/libxc/xc_domain.c   Tue Jun 13 12:12:24 2006 -0600
@@ -291,7 +291,7 @@ int xc_domain_memory_increase_reservatio
                                           unsigned long nr_extents,
                                           unsigned int extent_order,
                                           unsigned int address_bits,
-                                          unsigned long *extent_start)
+                                          xen_pfn_t *extent_start)
 {
     int err;
     struct xen_memory_reservation reservation = {
@@ -310,7 +310,7 @@ int xc_domain_memory_increase_reservatio
 
     if ( err > 0 )
     {
-        fprintf(stderr, "Failed allocation for dom %d: "
+        DPRINTF("Failed allocation for dom %d: "
                 "%ld pages order %d addr_bits %d\n",
                 domid, nr_extents, extent_order, address_bits);
         errno = ENOMEM;
@@ -324,7 +324,7 @@ int xc_domain_memory_decrease_reservatio
                                           uint32_t domid,
                                           unsigned long nr_extents,
                                           unsigned int extent_order,
-                                          unsigned long *extent_start)
+                                          xen_pfn_t *extent_start)
 {
     int err;
     struct xen_memory_reservation reservation = {
@@ -338,7 +338,7 @@ int xc_domain_memory_decrease_reservatio
 
     if ( extent_start == NULL )
     {
-        fprintf(stderr,"decrease_reservation extent_start is NULL!\n");
+        DPRINTF("decrease_reservation extent_start is NULL!\n");
         errno = EINVAL;
         return -1;
     }
@@ -349,7 +349,7 @@ int xc_domain_memory_decrease_reservatio
 
     if ( err > 0 )
     {
-        fprintf(stderr,"Failed deallocation for dom %d: %ld pages order %d\n",
+        DPRINTF("Failed deallocation for dom %d: %ld pages order %d\n",
                 domid, nr_extents, extent_order);
         errno = EBUSY;
         err = -1;
@@ -363,7 +363,7 @@ int xc_domain_memory_populate_physmap(in
                                           unsigned long nr_extents,
                                           unsigned int extent_order,
                                           unsigned int address_bits,
-                                          unsigned long *extent_start)
+                                          xen_pfn_t *extent_start)
 {
     int err;
     struct xen_memory_reservation reservation = {
@@ -380,7 +380,7 @@ int xc_domain_memory_populate_physmap(in
 
     if ( err > 0 )
     {
-        fprintf(stderr,"Failed deallocation for dom %d: %ld pages order %d\n",
+        DPRINTF("Failed deallocation for dom %d: %ld pages order %d\n",
                 domid, nr_extents, extent_order);
         errno = EBUSY;
         err = -1;
@@ -392,8 +392,8 @@ int xc_domain_translate_gpfn_list(int xc
 int xc_domain_translate_gpfn_list(int xc_handle,
                                   uint32_t domid,
                                   unsigned long nr_gpfns,
-                                  unsigned long *gpfn_list,
-                                  unsigned long *mfn_list)
+                                  xen_pfn_t *gpfn_list,
+                                  xen_pfn_t *mfn_list)
 {
     struct xen_translate_gpfn_list op = {
         .domid        = domid,
diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_hvm_build.c
--- a/tools/libxc/xc_hvm_build.c        Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/libxc/xc_hvm_build.c        Tue Jun 13 12:12:24 2006 -0600
@@ -135,7 +135,7 @@ static void set_hvm_info_checksum(struct
  * hvmloader will use this info to set BIOS accordingly
  */
 static int set_hvm_info(int xc_handle, uint32_t dom,
-                        unsigned long *pfn_list, unsigned int vcpus,
+                        xen_pfn_t *pfn_list, unsigned int vcpus,
                         unsigned int pae, unsigned int acpi, unsigned int apic)
 {
     char *va_map;
@@ -178,7 +178,7 @@ static int setup_guest(int xc_handle,
                        unsigned int store_evtchn,
                        unsigned long *store_mfn)
 {
-    unsigned long *page_array = NULL;
+    xen_pfn_t *page_array = NULL;
     unsigned long count, i;
     unsigned long long ptr;
     xc_mmu_t *mmu = NULL;
@@ -207,12 +207,12 @@ static int setup_guest(int xc_handle,
     /* memsize is in megabytes */
     v_end = (unsigned long long)memsize << 20;
 
-    printf("VIRTUAL MEMORY ARRANGEMENT:\n"
+    IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n"
            "  Loaded HVM loader:    %08lx->%08lx\n"
            "  TOTAL:                %08lx->%016llx\n",
            dsi.v_kernstart, dsi.v_kernend,
            dsi.v_start, v_end);
-    printf("  ENTRY ADDRESS:        %08lx\n", dsi.v_kernentry);
+    IPRINTF("  ENTRY ADDRESS:        %08lx\n", dsi.v_kernentry);
 
     if ( (v_end - dsi.v_start) > ((unsigned long long)nr_pages << PAGE_SHIFT) )
     {
@@ -223,7 +223,7 @@ static int setup_guest(int xc_handle,
         goto error_out;
     }
 
-    if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
+    if ( (page_array = malloc(nr_pages * sizeof(xen_pfn_t))) == NULL )
     {
         PERROR("Could not allocate memory.\n");
         goto error_out;
diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_ia64_stubs.c
--- a/tools/libxc/xc_ia64_stubs.c       Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/libxc/xc_ia64_stubs.c       Tue Jun 13 12:12:24 2006 -0600
@@ -57,7 +57,7 @@ xc_plan9_build(int xc_handle,
 
 int xc_ia64_get_pfn_list(int xc_handle,
                          uint32_t domid,
-                         unsigned long *pfn_buf,
+                         xen_pfn_t *pfn_buf,
                          unsigned int start_page,
                          unsigned int nr_pages)
 {
@@ -65,7 +65,7 @@ int xc_ia64_get_pfn_list(int xc_handle,
     int num_pfns,ret;
     unsigned int __start_page, __nr_pages;
     unsigned long max_pfns;
-    unsigned long *__pfn_buf;
+    xen_pfn_t *__pfn_buf;
 
     __start_page = start_page;
     __nr_pages = nr_pages;
@@ -80,7 +80,7 @@ int xc_ia64_get_pfn_list(int xc_handle,
         set_xen_guest_handle(op.u.getmemlist.buffer, __pfn_buf);
 
         if ( (max_pfns != -1UL)
-            && mlock(__pfn_buf, __nr_pages * sizeof(unsigned long)) != 0 )
+            && mlock(__pfn_buf, __nr_pages * sizeof(xen_pfn_t)) != 0 )
         {
             PERROR("Could not lock pfn list buffer");
             return -1;
@@ -89,7 +89,7 @@ int xc_ia64_get_pfn_list(int xc_handle,
         ret = do_dom0_op(xc_handle, &op);
 
         if (max_pfns != -1UL)
-            (void)munlock(__pfn_buf, __nr_pages * sizeof(unsigned long));
+            (void)munlock(__pfn_buf, __nr_pages * sizeof(xen_pfn_t));
 
         if (max_pfns == -1UL)
             return 0;
@@ -122,10 +122,10 @@ int xc_ia64_copy_to_domain_pages(int xc_
 {
     // N.B. gva should be page aligned
 
-    unsigned long *page_array = NULL;
+    xen_pfn_t *page_array = NULL;
     int i;
 
-    if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL ){
+    if ( (page_array = malloc(nr_pages * sizeof(xen_pfn_t))) == NULL ){
         PERROR("Could not allocate memory");
         goto error_out;
     }
@@ -669,7 +669,7 @@ static int setup_guest(  int xc_handle,
 
         vp_eport = xc_evtchn_alloc_unbound(xc_handle, dom, 0);
         if (vp_eport < 0) {
-            fprintf(stderr, "Couldn't get unbound port from VMX guest.\n");
+            DPRINTF("Couldn't get unbound port from VMX guest.\n");
             goto error_out;
         }
         sp->vcpu_iodata[i].vp_eport = vp_eport;
diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_linux.c
--- a/tools/libxc/xc_linux.c    Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/libxc/xc_linux.c    Tue Jun 13 12:12:24 2006 -0600
@@ -28,7 +28,7 @@ int xc_interface_close(int xc_handle)
 }
 
 void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot,
-                           unsigned long *arr, int num)
+                           xen_pfn_t *arr, int num)
 {
     privcmd_mmapbatch_t ioctlx;
     void *addr;
diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c      Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/libxc/xc_linux_build.c      Tue Jun 13 12:12:24 2006 -0600
@@ -10,6 +10,7 @@
 #include "xc_aout9.h"
 #include <stdlib.h>
 #include <unistd.h>
+#include <inttypes.h>
 #include <zlib.h>
 
 #if defined(__i386__)
@@ -136,7 +137,7 @@ int load_initrd(int xc_handle, domid_t d
 int load_initrd(int xc_handle, domid_t dom,
                 struct initrd_info *initrd,
                 unsigned long physbase,
-                unsigned long *phys_to_mach)
+                xen_pfn_t *phys_to_mach)
 {
     char page[PAGE_SIZE];
     unsigned long pfn_start, pfn, nr_pages;
@@ -189,7 +190,7 @@ static int setup_pg_tables(int xc_handle
                            vcpu_guest_context_t *ctxt,
                            unsigned long dsi_v_start,
                            unsigned long v_end,
-                           unsigned long *page_array,
+                           xen_pfn_t *page_array,
                            unsigned long vpt_start,
                            unsigned long vpt_end,
                            unsigned shadow_mode_enabled)
@@ -205,9 +206,9 @@ static int setup_pg_tables(int xc_handle
     alloc_pt(l2tab, vl2tab, pl2tab);
     vl2e = &vl2tab[l2_table_offset(dsi_v_start)];
     if (shadow_mode_enabled)
-        ctxt->ctrlreg[3] = pl2tab;
+        ctxt->ctrlreg[3] = xen_pfn_to_cr3(pl2tab >> PAGE_SHIFT);
     else
-        ctxt->ctrlreg[3] = l2tab;
+        ctxt->ctrlreg[3] = xen_pfn_to_cr3(l2tab >> PAGE_SHIFT);
 
     for ( count = 0; count < ((v_end - dsi_v_start) >> PAGE_SHIFT); count++ )
     {
@@ -251,26 +252,42 @@ static int setup_pg_tables_pae(int xc_ha
                                vcpu_guest_context_t *ctxt,
                                unsigned long dsi_v_start,
                                unsigned long v_end,
-                               unsigned long *page_array,
+                               xen_pfn_t *page_array,
                                unsigned long vpt_start,
                                unsigned long vpt_end,
-                               unsigned shadow_mode_enabled)
+                               unsigned shadow_mode_enabled,
+                               unsigned pae_mode)
 {
     l1_pgentry_64_t *vl1tab = NULL, *vl1e = NULL;
     l2_pgentry_64_t *vl2tab = NULL, *vl2e = NULL;
     l3_pgentry_64_t *vl3tab = NULL, *vl3e = NULL;
     uint64_t l1tab, l2tab, l3tab, pl1tab, pl2tab, pl3tab;
-    unsigned long ppt_alloc, count;
+    unsigned long ppt_alloc, count, nmfn;
 
     /* First allocate page for page dir. */
     ppt_alloc = (vpt_start - dsi_v_start) >> PAGE_SHIFT;
+
+    if ( pae_mode == PAEKERN_extended_cr3 )
+    {
+        ctxt->vm_assist |= (1UL << VMASST_TYPE_pae_extended_cr3);
+    }
+    else if ( page_array[ppt_alloc] > 0xfffff )
+    {
+        nmfn = xc_make_page_below_4G(xc_handle, dom, page_array[ppt_alloc]);
+        if ( nmfn == 0 )
+        {
+            DPRINTF("Couldn't get a page below 4GB :-(\n");
+            goto error_out;
+        }
+        page_array[ppt_alloc] = nmfn;
+    }
 
     alloc_pt(l3tab, vl3tab, pl3tab);
     vl3e = &vl3tab[l3_table_offset_pae(dsi_v_start)];
     if (shadow_mode_enabled)
-        ctxt->ctrlreg[3] = pl3tab;
+        ctxt->ctrlreg[3] = xen_pfn_to_cr3(pl3tab >> PAGE_SHIFT);
     else
-        ctxt->ctrlreg[3] = l3tab;
+        ctxt->ctrlreg[3] = xen_pfn_to_cr3(l3tab >> PAGE_SHIFT);
 
     for ( count = 0; count < ((v_end - dsi_v_start) >> PAGE_SHIFT); count++)
     {
@@ -340,7 +357,7 @@ static int setup_pg_tables_64(int xc_han
                               vcpu_guest_context_t *ctxt,
                               unsigned long dsi_v_start,
                               unsigned long v_end,
-                              unsigned long *page_array,
+                              xen_pfn_t *page_array,
                               unsigned long vpt_start,
                               unsigned long vpt_end,
                               int shadow_mode_enabled)
@@ -361,9 +378,9 @@ static int setup_pg_tables_64(int xc_han
     alloc_pt(l4tab, vl4tab, pl4tab);
     vl4e = &vl4tab[l4_table_offset(dsi_v_start)];
     if (shadow_mode_enabled)
-        ctxt->ctrlreg[3] = pl4tab;
+        ctxt->ctrlreg[3] = xen_pfn_to_cr3(pl4tab >> PAGE_SHIFT);
     else
-        ctxt->ctrlreg[3] = l4tab;
+        ctxt->ctrlreg[3] = xen_pfn_to_cr3(l4tab >> PAGE_SHIFT);
 
     for ( count = 0; count < ((v_end-dsi_v_start)>>PAGE_SHIFT); count++)
     {
@@ -451,7 +468,7 @@ static int setup_guest(int xc_handle,
                        unsigned int console_evtchn, unsigned long *console_mfn,
                        uint32_t required_features[XENFEAT_NR_SUBMAPS])
 {
-    unsigned long *page_array = NULL;
+    xen_pfn_t *page_array = NULL;
     struct load_funcs load_funcs;
     struct domain_setup_info dsi;
     unsigned long vinitrd_start;
@@ -478,7 +495,7 @@ static int setup_guest(int xc_handle,
 
     start_page = dsi.v_start >> PAGE_SHIFT;
     pgnr = (v_end - dsi.v_start) >> PAGE_SHIFT;
-    if ( (page_array = malloc(pgnr * sizeof(unsigned long))) == NULL )
+    if ( (page_array = malloc(pgnr * sizeof(xen_pfn_t))) == NULL )
     {
         PERROR("Could not allocate memory");
         goto error_out;
@@ -493,14 +510,14 @@ static int setup_guest(int xc_handle,
 
 #define _p(a) ((void *) (a))
 
-    printf("VIRTUAL MEMORY ARRANGEMENT:\n"
+    IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n"
            " Loaded kernel: %p->%p\n"
            " Init. ramdisk: %p->%p\n"
            " TOTAL:         %p->%p\n",
            _p(dsi.v_kernstart), _p(dsi.v_kernend),
            _p(vinitrd_start),   _p(vinitrd_end),
            _p(dsi.v_start),     _p(v_end));
-    printf(" ENTRY ADDRESS: %p\n", _p(dsi.v_kernentry));
+    IPRINTF(" ENTRY ADDRESS: %p\n", _p(dsi.v_kernentry));
 
     (load_funcs.loadimage)(image, image_size, xc_handle, dom, page_array,
                            &dsi);
@@ -524,7 +541,7 @@ static int setup_guest(int xc_handle,
 
     *store_mfn = page_array[1];
     *console_mfn = page_array[2];
-    printf("start_info: 0x%lx at 0x%lx, "
+    IPRINTF("start_info: 0x%lx at 0x%lx, "
            "store_mfn: 0x%lx at 0x%lx, "
            "console_mfn: 0x%lx at 0x%lx\n",
            page_array[0], nr_pages,
@@ -579,11 +596,11 @@ static int compat_check(int xc_handle, s
     }
 
     if (strstr(xen_caps, "xen-3.0-x86_32p")) {
-        if (!dsi->pae_kernel) {
+        if (dsi->pae_kernel == PAEKERN_no) {
             ERROR("Non PAE-kernel on PAE host.");
             return 0;
         }
-    } else if (dsi->pae_kernel) {
+    } else if (dsi->pae_kernel != PAEKERN_no) {
         ERROR("PAE-kernel on non-PAE host.");
         return 0;
     }
@@ -591,6 +608,16 @@ static int compat_check(int xc_handle, s
     return 1;
 }
 
+static inline int increment_ulong(unsigned long *pval, unsigned long inc)
+{
+    if ( inc >= -*pval )
+    {
+        ERROR("Value wrapped to zero: image too large?");
+        return 0;
+    }
+    *pval += inc;
+    return 1;
+}
 
 static int setup_guest(int xc_handle,
                        uint32_t dom,
@@ -606,7 +633,7 @@ static int setup_guest(int xc_handle,
                        unsigned int console_evtchn, unsigned long *console_mfn,
                        uint32_t required_features[XENFEAT_NR_SUBMAPS])
 {
-    unsigned long *page_array = NULL;
+    xen_pfn_t *page_array = NULL;
     unsigned long count, i, hypercall_pfn;
     start_info_t *start_info;
     shared_info_t *shared_info;
@@ -617,7 +644,7 @@ static int setup_guest(int xc_handle,
 
     unsigned long nr_pt_pages;
     unsigned long physmap_pfn;
-    unsigned long *physmap, *physmap_e;
+    xen_pfn_t *physmap, *physmap_e;
 
     struct load_funcs load_funcs;
     struct domain_setup_info dsi;
@@ -667,13 +694,14 @@ static int setup_guest(int xc_handle,
             goto error_out;
         }
 
-        printf("Supported features  = { %08x }.\n", supported_features[0]);
-        printf("Required features   = { %08x }.\n", required_features[0]);
+        IPRINTF("Supported features  = { %08x }.\n", supported_features[0]);
+        IPRINTF("Required features   = { %08x }.\n", required_features[0]);
     }
 
     for ( i = 0; i < XENFEAT_NR_SUBMAPS; i++ )
     {
-        if ( (supported_features[i]&required_features[i]) != 
required_features[i] )
+        if ( (supported_features[i] & required_features[i]) !=
+             required_features[i] )
         {
             ERROR("Guest kernel does not support a required feature.");
             goto error_out;
@@ -691,35 +719,64 @@ static int setup_guest(int xc_handle,
      * which we solve by exhaustive search.
      */
     v_end = round_pgup(dsi.v_end);
+    if ( v_end == 0 )
+    {
+        ERROR("End of mapped kernel image too close to end of memory");
+        goto error_out;
+    }
     vinitrd_start = v_end;
-    v_end += round_pgup(initrd->len);
+    if ( !increment_ulong(&v_end, round_pgup(initrd->len)) )
+        goto error_out;
     vphysmap_start = v_end;
-    v_end += round_pgup(nr_pages * sizeof(unsigned long));
+    if ( !increment_ulong(&v_end, round_pgup(nr_pages * sizeof(long))) )
+        goto error_out;
     vstartinfo_start = v_end;
-    v_end += PAGE_SIZE;
+    if ( !increment_ulong(&v_end, PAGE_SIZE) )
+        goto error_out;
     vstoreinfo_start = v_end;
-    v_end += PAGE_SIZE;
+    if ( !increment_ulong(&v_end, PAGE_SIZE) )
+        goto error_out;
     vconsole_start = v_end;
-    v_end += PAGE_SIZE;
+    if ( !increment_ulong(&v_end, PAGE_SIZE) )
+        goto error_out;
     if ( shadow_mode_enabled ) {
         vsharedinfo_start = v_end;
-        v_end += PAGE_SIZE;
+        if ( !increment_ulong(&v_end, PAGE_SIZE) )
+            goto error_out;
     }
     vpt_start = v_end;
 
     for ( nr_pt_pages = 2; ; nr_pt_pages++ )
     {
-        vpt_end          = vpt_start + (nr_pt_pages * PAGE_SIZE);
-        vstack_start     = vpt_end;
-        vstack_end       = vstack_start + PAGE_SIZE;
-        v_end            = (vstack_end + (1UL<<22)-1) & ~((1UL<<22)-1);
+        /* vpt_end = vpt_staret + (nr_pt_pages * PAGE_SIZE); */
+        vpt_end = vpt_start;
+        if ( !increment_ulong(&vpt_end, nr_pt_pages * PAGE_SIZE) )
+            goto error_out;
+
+        vstack_start = vpt_end;
+        /* vstack_end = vstack_start + PAGE_SIZE; */
+        vstack_end = vstack_start;
+        if ( !increment_ulong(&vstack_end, PAGE_SIZE) )
+            goto error_out;
+
+        /* v_end = (vstack_end + (1UL<<22)-1) & ~((1UL<<22)-1); */
+        v_end = vstack_end;
+        if ( !increment_ulong(&v_end, (1UL<<22)-1) )
+            goto error_out;
+        v_end &= ~((1UL<<22)-1);
+
         if ( (v_end - vstack_end) < (512UL << 10) )
-            v_end += 1UL << 22; /* Add extra 4MB to get >= 512kB padding. */
+        {
+            /* Add extra 4MB to get >= 512kB padding. */
+            if ( !increment_ulong(&v_end, 1UL << 22) )
+                goto error_out;
+        }
+
 #define NR(_l,_h,_s) \
     (((((_h) + ((1UL<<(_s))-1)) & ~((1UL<<(_s))-1)) - \
     ((_l) & ~((1UL<<(_s))-1))) >> (_s))
 #if defined(__i386__)
-        if ( dsi.pae_kernel )
+        if ( dsi.pae_kernel != PAEKERN_no )
         {
             if ( (1 + /* # L3 */
                   NR(dsi.v_start, v_end, L3_PAGETABLE_SHIFT_PAE) + /* # L2 */
@@ -748,22 +805,22 @@ static int setup_guest(int xc_handle,
 
 #define _p(a) ((void *) (a))
 
-    printf("VIRTUAL MEMORY ARRANGEMENT:\n");
-    printf(" Loaded kernel:    %p->%p\n", _p(dsi.v_kernstart),
+    IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n");
+    IPRINTF(" Loaded kernel:    %p->%p\n", _p(dsi.v_kernstart),
            _p(dsi.v_kernend));
     if ( initrd->len )
-        printf(" Initial ramdisk:  %p->%p\n", _p(vinitrd_start),
+        IPRINTF(" Initial ramdisk:  %p->%p\n", _p(vinitrd_start),
                _p(vinitrd_start + initrd->len));
-    printf(" Phys-Mach map:    %p\n", _p(vphysmap_start));
-    printf(" Start info:       %p\n", _p(vstartinfo_start));
-    printf(" Store page:       %p\n", _p(vstoreinfo_start));
-    printf(" Console page:     %p\n", _p(vconsole_start));
+    IPRINTF(" Phys-Mach map:    %p\n", _p(vphysmap_start));
+    IPRINTF(" Start info:       %p\n", _p(vstartinfo_start));
+    IPRINTF(" Store page:       %p\n", _p(vstoreinfo_start));
+    IPRINTF(" Console page:     %p\n", _p(vconsole_start));
     if ( shadow_mode_enabled )
-        printf(" Shared Info page: %p\n", _p(vsharedinfo_start));
-    printf(" Page tables:      %p\n", _p(vpt_start));
-    printf(" Boot stack:       %p\n", _p(vstack_start));
-    printf(" TOTAL:            %p->%p\n", _p(dsi.v_start), _p(v_end));
-    printf(" ENTRY ADDRESS:    %p\n", _p(dsi.v_kernentry));
+        IPRINTF(" Shared Info page: %p\n", _p(vsharedinfo_start));
+    IPRINTF(" Page tables:      %p\n", _p(vpt_start));
+    IPRINTF(" Boot stack:       %p\n", _p(vstack_start));
+    IPRINTF(" TOTAL:            %p->%p\n", _p(dsi.v_start), _p(v_end));
+    IPRINTF(" ENTRY ADDRESS:    %p\n", _p(dsi.v_kernentry));
 
     if ( ((v_end - dsi.v_start)>>PAGE_SHIFT) > nr_pages )
     {
@@ -797,11 +854,11 @@ static int setup_guest(int xc_handle,
 
     /* setup page tables */
 #if defined(__i386__)
-    if (dsi.pae_kernel)
+    if (dsi.pae_kernel != PAEKERN_no)
         rc = setup_pg_tables_pae(xc_handle, dom, ctxt,
                                  dsi.v_start, v_end,
                                  page_array, vpt_start, vpt_end,
-                                 shadow_mode_enabled);
+                                 shadow_mode_enabled, dsi.pae_kernel);
     else
         rc = setup_pg_tables(xc_handle, dom, ctxt,
                              dsi.v_start, v_end,
@@ -824,16 +881,16 @@ static int setup_guest(int xc_handle,
      */
     if ( !shadow_mode_enabled )
     {
-        if ( dsi.pae_kernel )
+        if ( dsi.pae_kernel != PAEKERN_no )
         {
             if ( pin_table(xc_handle, MMUEXT_PIN_L3_TABLE,
-                           ctxt->ctrlreg[3] >> PAGE_SHIFT, dom) )
+                           xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) )
                 goto error_out;
         }
         else
         {
             if ( pin_table(xc_handle, MMUEXT_PIN_L2_TABLE,
-                           ctxt->ctrlreg[3] >> PAGE_SHIFT, dom) )
+                           xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) )
                 goto error_out;
         }
     }
@@ -845,7 +902,7 @@ static int setup_guest(int xc_handle,
      * correct protection for the page
      */
     if ( pin_table(xc_handle, MMUEXT_PIN_L4_TABLE,
-                   ctxt->ctrlreg[3] >> PAGE_SHIFT, dom) )
+                   xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) )
         goto error_out;
 #endif
 
@@ -865,8 +922,8 @@ static int setup_guest(int xc_handle,
             ((uint64_t)page_array[count] << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE,
             count) )
         {
-            fprintf(stderr,"m2p update failure p=%lx m=%lx\n",
-                    count, page_array[count]);
+            DPRINTF("m2p update failure p=%lx m=%"PRIx64"\n",
+                    count, (uint64_t)page_array[count]);
             munmap(physmap, PAGE_SIZE);
             goto error_out;
         }
@@ -958,7 +1015,7 @@ static int setup_guest(int xc_handle,
     rc = xc_version(xc_handle, XENVER_version, NULL);
     sprintf(start_info->magic, "xen-%i.%i-x86_%d%s",
             rc >> 16, rc & (0xFFFF), (unsigned int)sizeof(long)*8,
-            dsi.pae_kernel ? "p" : "");
+            (dsi.pae_kernel != PAEKERN_no) ? "p" : "");
     start_info->nr_pages     = nr_pages;
     start_info->shared_info  = guest_shared_info_mfn << PAGE_SHIFT;
     start_info->flags        = flags;
diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_linux_restore.c
--- a/tools/libxc/xc_linux_restore.c    Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/libxc/xc_linux_restore.c    Tue Jun 13 12:12:24 2006 -0600
@@ -25,10 +25,10 @@ static unsigned long max_pfn;
 static unsigned long max_pfn;
 
 /* Live mapping of the table mapping each PFN to its current MFN. */
-static unsigned long *live_p2m = NULL;
+static xen_pfn_t *live_p2m = NULL;
 
 /* A table mapping each PFN to its new MFN. */
-static unsigned long *p2m = NULL;
+static xen_pfn_t *p2m = NULL;
 
 
 static ssize_t
@@ -108,7 +108,7 @@ int xc_linux_restore(int xc_handle, int 
                      unsigned int console_evtchn, unsigned long *console_mfn)
 {
     DECLARE_DOM0_OP;
-    int rc = 1, i, n;
+    int rc = 1, i, n, pae_extended_cr3 = 0;
     unsigned long mfn, pfn;
     unsigned int prev_pc, this_pc;
     int verify = 0;
@@ -126,7 +126,7 @@ int xc_linux_restore(int xc_handle, int 
     unsigned long *pfn_type = NULL;
 
     /* A table of MFNs to map in the current region */
-    unsigned long *region_mfn = NULL;
+    xen_pfn_t *region_mfn = NULL;
 
     /* Types of the pfns in the current region */
     unsigned long region_pfn_type[MAX_BATCH_SIZE];
@@ -135,7 +135,7 @@ int xc_linux_restore(int xc_handle, int 
     unsigned long *page = NULL;
 
     /* A copy of the pfn-to-mfn table frame list. */
-    unsigned long *p2m_frame_list = NULL;
+    xen_pfn_t *p2m_frame_list = NULL;
 
     /* A temporary mapping of the guest's start_info page. */
     start_info_t *start_info;
@@ -162,30 +162,88 @@ int xc_linux_restore(int xc_handle, int 
         return 1;
     }
 
-
     if (mlock(&ctxt, sizeof(ctxt))) {
         /* needed for build dom0 op, but might as well do early */
         ERR("Unable to mlock ctxt");
         return 1;
     }
 
-
-    /* Read the saved P2M frame list */
-    if(!(p2m_frame_list = malloc(P2M_FL_SIZE))) {
+    if (!(p2m_frame_list = malloc(P2M_FL_SIZE))) {
         ERR("Couldn't allocate p2m_frame_list array");
         goto out;
     }
 
-    if (!read_exact(io_fd, p2m_frame_list, P2M_FL_SIZE)) {
+    /* Read first entry of P2M list, or extended-info signature (~0UL). */
+    if (!read_exact(io_fd, p2m_frame_list, sizeof(long))) {
+        ERR("read extended-info signature failed");
+        goto out;
+    }
+
+    if (p2m_frame_list[0] == ~0UL) {
+        uint32_t tot_bytes;
+
+        /* Next 4 bytes: total size of following extended info. */
+        if (!read_exact(io_fd, &tot_bytes, sizeof(tot_bytes))) {
+            ERR("read extended-info size failed");
+            goto out;
+        }
+
+        while (tot_bytes) {
+            uint32_t chunk_bytes;
+            char     chunk_sig[4];
+
+            /* 4-character chunk signature + 4-byte remaining chunk size. */
+            if (!read_exact(io_fd, chunk_sig, sizeof(chunk_sig)) ||
+                !read_exact(io_fd, &chunk_bytes, sizeof(chunk_bytes))) {
+                ERR("read extended-info chunk signature failed");
+                goto out;
+            }
+            tot_bytes -= 8;
+
+            /* VCPU context structure? */
+            if (!strncmp(chunk_sig, "vcpu", 4)) {
+                if (!read_exact(io_fd, &ctxt, sizeof(ctxt))) {
+                    ERR("read extended-info vcpu context failed");
+                    goto out;
+                }
+                tot_bytes   -= sizeof(struct vcpu_guest_context);
+                chunk_bytes -= sizeof(struct vcpu_guest_context);
+
+                if (ctxt.vm_assist & (1UL << VMASST_TYPE_pae_extended_cr3))
+                    pae_extended_cr3 = 1;
+            }
+
+            /* Any remaining bytes of this chunk: read and discard. */
+            while (chunk_bytes) {
+                unsigned long sz = chunk_bytes;
+                if ( sz > P2M_FL_SIZE )
+                    sz = P2M_FL_SIZE;
+                if (!read_exact(io_fd, p2m_frame_list, sz)) {
+                    ERR("read-and-discard extended-info chunk bytes failed");
+                    goto out;
+                }
+                chunk_bytes -= sz;
+                tot_bytes   -= sz;
+            }
+        }
+
+        /* Now read the real first entry of P2M list. */
+        if (!read_exact(io_fd, p2m_frame_list, sizeof(long))) {
+            ERR("read first entry of p2m_frame_list failed");
+            goto out;
+        }
+    }
+
+    /* First entry is already read into the p2m array. */
+    if (!read_exact(io_fd, &p2m_frame_list[1], P2M_FL_SIZE - sizeof(long))) {
         ERR("read p2m_frame_list failed");
         goto out;
     }
 
-
     /* We want zeroed memory so use calloc rather than malloc. */
-    p2m        = calloc(max_pfn, sizeof(unsigned long));
+    p2m        = calloc(max_pfn, sizeof(xen_pfn_t));
     pfn_type   = calloc(max_pfn, sizeof(unsigned long));
-    region_mfn = calloc(MAX_BATCH_SIZE, sizeof(unsigned long));
+    region_mfn = calloc(MAX_BATCH_SIZE, sizeof(xen_pfn_t));
 
     if ((p2m == NULL) || (pfn_type == NULL) || (region_mfn == NULL)) {
         ERR("memory alloc failed");
@@ -193,7 +251,7 @@ int xc_linux_restore(int xc_handle, int 
         goto out;
     }
 
-    if (mlock(region_mfn, sizeof(unsigned long) * MAX_BATCH_SIZE)) {
+    if (mlock(region_mfn, sizeof(xen_pfn_t) * MAX_BATCH_SIZE)) {
         ERR("Could not mlock region_mfn");
         goto out;
     }
@@ -262,7 +320,7 @@ int xc_linux_restore(int xc_handle, int 
 
         if (j == -1) {
             verify = 1;
-            fprintf(stderr, "Entering page verify mode\n");
+            DPRINTF("Entering page verify mode\n");
             continue;
         }
 
@@ -331,17 +389,27 @@ int xc_linux_restore(int xc_handle, int 
                 ** A page table page - need to 'uncanonicalize' it, i.e.
                 ** replace all the references to pfns with the corresponding
                 ** mfns for the new domain.
+                **
+                ** On PAE we need to ensure that PGDs are in MFNs < 4G, and
+                ** so we may need to update the p2m after the main loop.
+                ** Hence we defer canonicalization of L1s until then.
                 */
-                if(!uncanonicalize_pagetable(pagetype, page)) {
-                    /*
-                    ** Failing to uncanonicalize a page table can be ok
-                    ** under live migration since the pages type may have
-                    ** changed by now (and we'll get an update later).
-                    */
-                    DPRINTF("PT L%ld race on pfn=%08lx mfn=%08lx\n",
-                            pagetype >> 28, pfn, mfn);
-                    nraces++;
-                    continue;
+                if ((pt_levels != 3) ||
+                    pae_extended_cr3 ||
+                    (pagetype != L1TAB)) {
+
+                    if (!uncanonicalize_pagetable(pagetype, page)) {
+                        /*
+                        ** Failing to uncanonicalize a page table can be ok
+                        ** under live migration since the pages type may have
+                        ** changed by now (and we'll get an update later).
+                        */
+                        DPRINTF("PT L%ld race on pfn=%08lx mfn=%08lx\n",
+                                pagetype >> 28, pfn, mfn);
+                        nraces++;
+                        continue;
+                    }
+
                 }
 
             } else if(pagetype != NOTAB) {
@@ -389,6 +457,100 @@ int xc_linux_restore(int xc_handle, int 
     }
 
     DPRINTF("Received all pages (%d races)\n", nraces);
+
+    if ((pt_levels == 3) && !pae_extended_cr3) {
+
+        /*
+        ** XXX SMH on PAE we need to ensure PGDs are in MFNs < 4G. This
+        ** is a little awkward and involves (a) finding all such PGDs and
+        ** replacing them with 'lowmem' versions; (b) upating the p2m[]
+        ** with the new info; and (c) canonicalizing all the L1s using the
+        ** (potentially updated) p2m[].
+        **
+        ** This is relatively slow (and currently involves two passes through
+        ** the pfn_type[] array), but at least seems to be correct. May wish
+        ** to consider more complex approaches to optimize this later.
+        */
+
+        int j, k;
+
+        /* First pass: find all L3TABs current in > 4G mfns and get new mfns */
+        for (i = 0; i < max_pfn; i++) {
+
+            if (((pfn_type[i] & LTABTYPE_MASK)==L3TAB) && (p2m[i]>0xfffffUL)) {
+
+                unsigned long new_mfn;
+                uint64_t l3ptes[4];
+                uint64_t *l3tab;
+
+                l3tab = (uint64_t *)
+                    xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+                                         PROT_READ, p2m[i]);
+
+                for(j = 0; j < 4; j++)
+                    l3ptes[j] = l3tab[j];
+
+                munmap(l3tab, PAGE_SIZE);
+
+                if (!(new_mfn=xc_make_page_below_4G(xc_handle, dom, p2m[i]))) {
+                    ERR("Couldn't get a page below 4GB :-(");
+                    goto out;
+                }
+
+                p2m[i] = new_mfn;
+                if (xc_add_mmu_update(xc_handle, mmu,
+                                      (((unsigned long long)new_mfn)
+                                       << PAGE_SHIFT) |
+                                      MMU_MACHPHYS_UPDATE, i)) {
+                    ERR("Couldn't m2p on PAE root pgdir");
+                    goto out;
+                }
+
+                l3tab = (uint64_t *)
+                    xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+                                         PROT_READ | PROT_WRITE, p2m[i]);
+
+                for(j = 0; j < 4; j++)
+                    l3tab[j] = l3ptes[j];
+
+                munmap(l3tab, PAGE_SIZE);
+
+            }
+        }
+
+        /* Second pass: find all L1TABs and uncanonicalize them */
+        j = 0;
+
+        for(i = 0; i < max_pfn; i++) {
+
+            if (((pfn_type[i] & LTABTYPE_MASK)==L1TAB)) {
+                region_mfn[j] = p2m[i];
+                j++;
+            }
+
+            if(i == (max_pfn-1) || j == MAX_BATCH_SIZE) {
+
+                if (!(region_base = xc_map_foreign_batch(
+                          xc_handle, dom, PROT_READ | PROT_WRITE,
+                          region_mfn, j))) {
+                    ERR("map batch failed");
+                    goto out;
+                }
+
+                for(k = 0; k < j; k++) {
+                    if(!uncanonicalize_pagetable(L1TAB,
+                                                 region_base + k*PAGE_SIZE)) {
+                        ERR("failed uncanonicalize pt!");
+                        goto out;
+                    }
+                }
+
+                munmap(region_base, j*PAGE_SIZE);
+                j = 0;
+            }
+        }
+
+    }
 
 
     if (xc_finish_mmu_updates(xc_handle, mmu)) {
@@ -536,7 +698,7 @@ int xc_linux_restore(int xc_handle, int 
     }
 
     /* Uncanonicalise the page table base pointer. */
-    pfn = ctxt.ctrlreg[3] >> PAGE_SHIFT;
+    pfn = xen_cr3_to_pfn(ctxt.ctrlreg[3]);
 
     if (pfn >= max_pfn) {
         ERR("PT base is bad: pfn=%lu max_pfn=%lu type=%08lx",
@@ -552,7 +714,7 @@ int xc_linux_restore(int xc_handle, int 
         goto out;
     }
 
-    ctxt.ctrlreg[3] = p2m[pfn] << PAGE_SHIFT;
+    ctxt.ctrlreg[3] = xen_pfn_to_cr3(p2m[pfn]);
 
     /* clear any pending events and the selector */
     memset(&(shared_info->evtchn_pending[0]), 0,
diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_linux_save.c
--- a/tools/libxc/xc_linux_save.c       Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/libxc/xc_linux_save.c       Tue Jun 13 12:12:24 2006 -0600
@@ -40,10 +40,10 @@ static unsigned long max_pfn;
 static unsigned long max_pfn;
 
 /* Live mapping of the table mapping each PFN to its current MFN. */
-static unsigned long *live_p2m = NULL;
+static xen_pfn_t *live_p2m = NULL;
 
 /* Live mapping of system MFN to PFN table. */
-static unsigned long *live_m2p = NULL;
+static xen_pfn_t *live_m2p = NULL;
 
 /* grep fodder: machine_to_phys */
 
@@ -288,7 +288,7 @@ static int print_stats(int xc_handle, ui
     d1_cpu_now = xc_domain_get_cpu_usage(xc_handle, domid, /* FIXME */ 0)/1000;
 
     if ( (d0_cpu_now == -1) || (d1_cpu_now == -1) )
-        fprintf(stderr, "ARRHHH!!\n");
+        DPRINTF("ARRHHH!!\n");
 
     wall_delta = tv_delta(&wall_now,&wall_last)/1000;
 
@@ -298,7 +298,7 @@ static int print_stats(int xc_handle, ui
     d1_cpu_delta = (d1_cpu_now - d1_cpu_last)/1000;
 
     if (print)
-        fprintf(stderr,
+        DPRINTF(
                 "delta %lldms, dom0 %d%%, target %d%%, sent %dMb/s, "
                 "dirtied %dMb/s %" PRId32 " pages\n",
                 wall_delta,
@@ -339,14 +339,14 @@ static int analysis_phase(int xc_handle,
 
         xc_shadow_control(xc_handle, domid, DOM0_SHADOW_CONTROL_OP_CLEAN,
                           arr, max_pfn, NULL);
-        fprintf(stderr, "#Flush\n");
+        DPRINTF("#Flush\n");
         for ( i = 0; i < 40; i++ ) {
             usleep(50000);
             now = llgettimeofday();
             xc_shadow_control(xc_handle, domid, DOM0_SHADOW_CONTROL_OP_PEEK,
                               NULL, 0, &stats);
 
-            fprintf(stderr, "now= %lld faults= %" PRId32 " dirty= %" PRId32
+            DPRINTF("now= %lld faults= %" PRId32 " dirty= %" PRId32
                     " dirty_net= %" PRId32 " dirty_block= %" PRId32"\n",
                     ((now-start)+500)/1000,
                     stats.fault_count, stats.dirty_count,
@@ -501,22 +501,22 @@ void canonicalize_pagetable(unsigned lon
 
 
 
-static unsigned long *xc_map_m2p(int xc_handle,
+static xen_pfn_t *xc_map_m2p(int xc_handle,
                                  unsigned long max_mfn,
                                  int prot)
 {
     struct xen_machphys_mfn_list xmml;
     privcmd_mmap_entry_t *entries;
     unsigned long m2p_chunks, m2p_size;
-    unsigned long *m2p;
-    unsigned long *extent_start;
+    xen_pfn_t *m2p;
+    xen_pfn_t *extent_start;
     int i, rc;
 
     m2p_size   = M2P_SIZE(max_mfn);
     m2p_chunks = M2P_CHUNKS(max_mfn);
 
     xmml.max_extents = m2p_chunks;
-    if (!(extent_start = malloc(m2p_chunks * sizeof(unsigned long)))) {
+    if (!(extent_start = malloc(m2p_chunks * sizeof(xen_pfn_t)))) {
         ERR("failed to allocate space for m2p mfns");
         return NULL;
     }
@@ -583,11 +583,11 @@ int xc_linux_save(int xc_handle, int io_
     char page[PAGE_SIZE];
 
     /* Double and single indirect references to the live P2M table */
-    unsigned long *live_p2m_frame_list_list = NULL;
-    unsigned long *live_p2m_frame_list = NULL;
+    xen_pfn_t *live_p2m_frame_list_list = NULL;
+    xen_pfn_t *live_p2m_frame_list = NULL;
 
     /* A copy of the pfn-to-mfn table frame list. */
-    unsigned long *p2m_frame_list = NULL;
+    xen_pfn_t *p2m_frame_list = NULL;
 
     /* Live mapping of shared info structure */
     shared_info_t *live_shinfo = NULL;
@@ -712,11 +712,11 @@ int xc_linux_save(int xc_handle, int io_
     memcpy(p2m_frame_list, live_p2m_frame_list, P2M_FL_SIZE);
 
     /* Canonicalise the pfn-to-mfn table frame-number list. */
-    for (i = 0; i < max_pfn; i += ulpp) {
-        if (!translate_mfn_to_pfn(&p2m_frame_list[i/ulpp])) {
+    for (i = 0; i < max_pfn; i += fpp) {
+        if (!translate_mfn_to_pfn(&p2m_frame_list[i/fpp])) {
             ERR("Frame# in pfn-to-mfn frame list is not in pseudophys");
-            ERR("entry %d: p2m_frame_list[%ld] is 0x%lx", i, i/ulpp,
-                p2m_frame_list[i/ulpp]);
+            ERR("entry %d: p2m_frame_list[%ld] is 0x%"PRIx64, i, i/fpp,
+                (uint64_t)p2m_frame_list[i/fpp]);
             goto out;
         }
     }
@@ -818,12 +818,33 @@ int xc_linux_save(int xc_handle, int io_
 
     /* Start writing out the saved-domain record. */
 
-    if(!write_exact(io_fd, &max_pfn, sizeof(unsigned long))) {
+    if (!write_exact(io_fd, &max_pfn, sizeof(unsigned long))) {
         ERR("write: max_pfn");
         goto out;
     }
 
-    if(!write_exact(io_fd, p2m_frame_list, P2M_FL_SIZE)) {
+    /*
+     * Write an extended-info structure to inform the restore code that
+     * a PAE guest understands extended CR3 (PDPTs above 4GB). Turns off
+     * slow paths in the restore code.
+     */
+    if ((pt_levels == 3) &&
+        (ctxt.vm_assist & (1UL << VMASST_TYPE_pae_extended_cr3))) {
+        unsigned long signature = ~0UL;
+        uint32_t tot_sz   = sizeof(struct vcpu_guest_context) + 8;
+        uint32_t chunk_sz = sizeof(struct vcpu_guest_context);
+        char chunk_sig[]  = "vcpu";
+        if (!write_exact(io_fd, &signature, sizeof(signature)) ||
+            !write_exact(io_fd, &tot_sz,    sizeof(tot_sz)) ||
+            !write_exact(io_fd, &chunk_sig, 4) ||
+            !write_exact(io_fd, &chunk_sz,  sizeof(chunk_sz)) ||
+            !write_exact(io_fd, &ctxt,      sizeof(ctxt))) {
+            ERR("write: extended info");
+            goto out;
+        }
+    }
+
+    if (!write_exact(io_fd, p2m_frame_list, P2M_FL_SIZE)) {
         ERR("write: p2m_frame_list");
         goto out;
     }
@@ -940,7 +961,7 @@ int xc_linux_save(int xc_handle, int io_
                 }
 
                 if (debug)
-                    fprintf(stderr, "%d pfn= %08lx mfn= %08lx [mfn]= %08lx"
+                    DPRINTF("%d pfn= %08lx mfn= %08lx [mfn]= %08lx"
                             " sum= %08lx\n",
                             iter,
                             (pfn_type[j] & LTAB_MASK) | pfn_batch[j],
@@ -1021,7 +1042,7 @@ int xc_linux_save(int xc_handle, int io_
             int minusone = -1;
             memset(to_send, 0xff, BITMAP_SIZE);
             debug = 0;
-            fprintf(stderr, "Entering debug resend-all mode\n");
+            DPRINTF("Entering debug resend-all mode\n");
 
             /* send "-1" to put receiver into debug mode */
             if(!write_exact(io_fd, &minusone, sizeof(int))) {
@@ -1129,12 +1150,12 @@ int xc_linux_save(int xc_handle, int io_
     }
 
     /* Canonicalise the page table base pointer. */
-    if ( !MFN_IS_IN_PSEUDOPHYS_MAP(ctxt.ctrlreg[3] >> PAGE_SHIFT) ) {
+    if ( !MFN_IS_IN_PSEUDOPHYS_MAP(xen_cr3_to_pfn(ctxt.ctrlreg[3])) ) {
         ERR("PT base is not in range of pseudophys map");
         goto out;
     }
-    ctxt.ctrlreg[3] = mfn_to_pfn(ctxt.ctrlreg[3] >> PAGE_SHIFT) <<
-        PAGE_SHIFT;
+    ctxt.ctrlreg[3] = 
+        xen_pfn_to_cr3(mfn_to_pfn(xen_cr3_to_pfn(ctxt.ctrlreg[3])));
 
     if (!write_exact(io_fd, &ctxt, sizeof(ctxt)) ||
         !write_exact(io_fd, live_shinfo, PAGE_SIZE)) {
diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_load_aout9.c
--- a/tools/libxc/xc_load_aout9.c       Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/libxc/xc_load_aout9.c       Tue Jun 13 12:12:24 2006 -0600
@@ -17,7 +17,7 @@
 #define KOFFSET(_p)       ((_p)&~KZERO)
 
 static int parseaout9image(const char *, unsigned long, struct 
domain_setup_info *);
-static int loadaout9image(const char *, unsigned long, int, uint32_t, unsigned 
long *, struct domain_setup_info *);
+static int loadaout9image(const char *, unsigned long, int, uint32_t, 
xen_pfn_t *, struct domain_setup_info *);
 static void copyout(int, uint32_t, unsigned long *, unsigned long, const char 
*, int);
 struct Exec *get_header(const char *, unsigned long, struct Exec *);
 
@@ -79,7 +79,7 @@ loadaout9image(
     const char *image,
     unsigned long image_size,
     int xch, uint32_t dom,
-    unsigned long *parray,
+    xen_pfn_t *parray,
     struct domain_setup_info *dsi)
 {
     struct Exec ehdr;
diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_load_bin.c
--- a/tools/libxc/xc_load_bin.c Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/libxc/xc_load_bin.c Tue Jun 13 12:12:24 2006 -0600
@@ -107,7 +107,7 @@ static int
 static int
 loadbinimage(
     const char *image, unsigned long image_size, int xch, uint32_t dom,
-    unsigned long *parray, struct domain_setup_info *dsi);
+    xen_pfn_t *parray, struct domain_setup_info *dsi);
 
 int probe_bin(const char *image,
               unsigned long image_size,
@@ -235,7 +235,7 @@ static int
 static int
 loadbinimage(
     const char *image, unsigned long image_size, int xch, uint32_t dom,
-    unsigned long *parray, struct domain_setup_info *dsi)
+    xen_pfn_t *parray, struct domain_setup_info *dsi)
 {
     unsigned long size;
     char         *va;
diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_load_elf.c
--- a/tools/libxc/xc_load_elf.c Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/libxc/xc_load_elf.c Tue Jun 13 12:12:24 2006 -0600
@@ -16,10 +16,10 @@ static int
 static int
 loadelfimage(
     const char *image, unsigned long image_size, int xch, uint32_t dom,
-    unsigned long *parray, struct domain_setup_info *dsi);
+    xen_pfn_t *parray, struct domain_setup_info *dsi);
 static int
 loadelfsymtab(
-    const char *image, int xch, uint32_t dom, unsigned long *parray,
+    const char *image, int xch, uint32_t dom, xen_pfn_t *parray,
     struct domain_setup_info *dsi);
 
 int probe_elf(const char *image,
@@ -122,8 +122,15 @@ static int parseelfimage(const char *ima
             ERROR("Actually saw: '%s'", guestinfo);
             return -EINVAL;
         }
-        if ( (strstr(guestinfo, "PAE=yes") != NULL) )
-            dsi->pae_kernel = 1;
+
+        dsi->pae_kernel = PAEKERN_no;
+        p = strstr(guestinfo, "PAE=yes");
+        if ( p != NULL )
+        {
+            dsi->pae_kernel = PAEKERN_yes;
+            if ( !strncmp(p+7, "[extended-cr3]", 14) )
+                dsi->pae_kernel = PAEKERN_extended_cr3;
+        }
 
         break;
     }
@@ -204,7 +211,7 @@ static int
 static int
 loadelfimage(
     const char *image, unsigned long elfsize, int xch, uint32_t dom,
-    unsigned long *parray, struct domain_setup_info *dsi)
+    xen_pfn_t *parray, struct domain_setup_info *dsi)
 {
     Elf_Ehdr *ehdr = (Elf_Ehdr *)image;
     Elf_Phdr *phdr;
@@ -258,7 +265,7 @@ loadelfimage(
 
 static int
 loadelfsymtab(
-    const char *image, int xch, uint32_t dom, unsigned long *parray,
+    const char *image, int xch, uint32_t dom, xen_pfn_t *parray,
     struct domain_setup_info *dsi)
 {
     Elf_Ehdr *ehdr = (Elf_Ehdr *)image, *sym_ehdr;
diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_pagetab.c
--- a/tools/libxc/xc_pagetab.c  Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/libxc/xc_pagetab.c  Tue Jun 13 12:12:24 2006 -0600
@@ -75,10 +75,10 @@ unsigned long xc_translate_foreign_addre
 #endif
 
     if (xc_vcpu_getcontext(xc_handle, dom, vcpu, &ctx) != 0) {
-        fprintf(stderr, "failed to retreive vcpu context\n");
+        DPRINTF("failed to retreive vcpu context\n");
         goto out;
     }
-    cr3 = ctx.ctrlreg[3];
+    cr3 = ((unsigned long long)xen_cr3_to_pfn(ctx.ctrlreg[3])) << PAGE_SHIFT;
 
     /* Page Map Level 4 */
 
@@ -87,12 +87,12 @@ unsigned long xc_translate_foreign_addre
 #elif defined(__x86_64__)
     pml = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ, cr3 >> 
PAGE_SHIFT);
     if (pml == NULL) {
-        fprintf(stderr, "failed to map PML4\n");
+        DPRINTF("failed to map PML4\n");
         goto out;
     }
     pmle = *(unsigned long long *)(pml + 8 * ((virt >> L4_PAGETABLE_SHIFT_PAE) 
& L4_PAGETABLE_MASK_PAE));
     if((pmle & 1) == 0) {
-        fprintf(stderr, "page entry not present in PML4\n");
+        DPRINTF("page entry not present in PML4\n");
         goto out_unmap_pml;
     }
 #endif
@@ -102,7 +102,7 @@ unsigned long xc_translate_foreign_addre
     if (pt_levels >= 3) {
         pdppage = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ, 
pmle >> PAGE_SHIFT);
         if (pdppage == NULL) {
-            fprintf(stderr, "failed to map PDP\n");
+            DPRINTF("failed to map PDP\n");
             goto out_unmap_pml;
         }
         if (pt_levels >= 4)
@@ -114,7 +114,7 @@ unsigned long xc_translate_foreign_addre
         pdpe = *(unsigned long long *)(pdp + 8 * ((virt >> 
L3_PAGETABLE_SHIFT_PAE) & L3_PAGETABLE_MASK_PAE));
 
         if((pdpe & 1) == 0) {
-            fprintf(stderr, "page entry not present in PDP\n");
+            DPRINTF("page entry not present in PDP\n");
             goto out_unmap_pdp;
         }
     } else {
@@ -125,7 +125,7 @@ unsigned long xc_translate_foreign_addre
 
     pd = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ, pdpe >> 
PAGE_SHIFT);
     if (pd == NULL) {
-        fprintf(stderr, "failed to map PD\n");
+        DPRINTF("failed to map PD\n");
         goto out_unmap_pdp;
     }
 
@@ -135,21 +135,21 @@ unsigned long xc_translate_foreign_addre
         pde = *(unsigned long long *)(pd + 4 * ((virt >> L2_PAGETABLE_SHIFT) & 
L2_PAGETABLE_MASK));
 
     if ((pde & 1) == 0) {
-        fprintf(stderr, "page entry not present in PD\n");
+        DPRINTF("page entry not present in PD\n");
         goto out_unmap_pd;
     }
 
     /* Page Table */
 
     if (pde & 0x00000008) { /* 4M page (or 2M in PAE mode) */
-        fprintf(stderr, "Cannot currently cope with 2/4M pages\n");
+        DPRINTF("Cannot currently cope with 2/4M pages\n");
         exit(-1);
     } else { /* 4k page */
         pt = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ,
                                   pde >> PAGE_SHIFT);
 
         if (pt == NULL) {
-            fprintf(stderr, "failed to map PT\n");
+            DPRINTF("failed to map PT\n");
             goto out_unmap_pd;
         }
 
@@ -159,7 +159,7 @@ unsigned long xc_translate_foreign_addre
             pte = *(unsigned long long *)(pt + 4 * ((virt >> 
L1_PAGETABLE_SHIFT) & L1_PAGETABLE_MASK));
 
         if ((pte & 0x00000001) == 0) {
-            fprintf(stderr, "page entry not present in PT\n");
+            DPRINTF("page entry not present in PT\n");
             goto out_unmap_pt;
         }
 
diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_private.c
--- a/tools/libxc/xc_private.c  Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/libxc/xc_private.c  Tue Jun 13 12:12:24 2006 -0600
@@ -4,6 +4,7 @@
  * Helper functions for the rest of the library.
  */
 
+#include <inttypes.h>
 #include "xc_private.h"
 
 /* NB: arr must be mlock'ed */
@@ -134,9 +135,9 @@ int xc_memory_op(int xc_handle,
     struct xen_memory_reservation *reservation = arg;
     struct xen_machphys_mfn_list *xmml = arg;
     struct xen_translate_gpfn_list *trans = arg;
-    unsigned long *extent_start;
-    unsigned long *gpfn_list;
-    unsigned long *mfn_list;
+    xen_pfn_t *extent_start;
+    xen_pfn_t *gpfn_list;
+    xen_pfn_t *mfn_list;
     long ret = -EINVAL;
 
     hypercall.op     = __HYPERVISOR_memory_op;
@@ -156,7 +157,7 @@ int xc_memory_op(int xc_handle,
         get_xen_guest_handle(extent_start, reservation->extent_start);
         if ( (extent_start != NULL) &&
              (mlock(extent_start,
-                    reservation->nr_extents * sizeof(unsigned long)) != 0) )
+                    reservation->nr_extents * sizeof(xen_pfn_t)) != 0) )
         {
             PERROR("Could not mlock");
             safe_munlock(reservation, sizeof(*reservation));
@@ -171,7 +172,7 @@ int xc_memory_op(int xc_handle,
         }
         get_xen_guest_handle(extent_start, xmml->extent_start);
         if ( mlock(extent_start,
-                   xmml->max_extents * sizeof(unsigned long)) != 0 )
+                   xmml->max_extents * sizeof(xen_pfn_t)) != 0 )
         {
             PERROR("Could not mlock");
             safe_munlock(xmml, sizeof(*xmml));
@@ -192,17 +193,17 @@ int xc_memory_op(int xc_handle,
             goto out1;
         }
         get_xen_guest_handle(gpfn_list, trans->gpfn_list);
-        if ( mlock(gpfn_list, trans->nr_gpfns * sizeof(long)) != 0 )
+        if ( mlock(gpfn_list, trans->nr_gpfns * sizeof(xen_pfn_t)) != 0 )
         {
             PERROR("Could not mlock");
             safe_munlock(trans, sizeof(*trans));
             goto out1;
         }
         get_xen_guest_handle(mfn_list, trans->mfn_list);
-        if ( mlock(mfn_list, trans->nr_gpfns * sizeof(long)) != 0 )
-        {
-            PERROR("Could not mlock");
-            safe_munlock(gpfn_list, trans->nr_gpfns * sizeof(long));
+        if ( mlock(mfn_list, trans->nr_gpfns * sizeof(xen_pfn_t)) != 0 )
+        {
+            PERROR("Could not mlock");
+            safe_munlock(gpfn_list, trans->nr_gpfns * sizeof(xen_pfn_t));
             safe_munlock(trans, sizeof(*trans));
             goto out1;
         }
@@ -220,22 +221,22 @@ int xc_memory_op(int xc_handle,
         get_xen_guest_handle(extent_start, reservation->extent_start);
         if ( extent_start != NULL )
             safe_munlock(extent_start,
-                         reservation->nr_extents * sizeof(unsigned long));
+                         reservation->nr_extents * sizeof(xen_pfn_t));
         break;
     case XENMEM_machphys_mfn_list:
         safe_munlock(xmml, sizeof(*xmml));
         get_xen_guest_handle(extent_start, xmml->extent_start);
         safe_munlock(extent_start,
-                     xmml->max_extents * sizeof(unsigned long));
+                     xmml->max_extents * sizeof(xen_pfn_t));
         break;
     case XENMEM_add_to_physmap:
         safe_munlock(arg, sizeof(struct xen_add_to_physmap));
         break;
     case XENMEM_translate_gpfn_list:
             get_xen_guest_handle(mfn_list, trans->mfn_list);
-            safe_munlock(mfn_list, trans->nr_gpfns * sizeof(long));
+            safe_munlock(mfn_list, trans->nr_gpfns * sizeof(xen_pfn_t));
             get_xen_guest_handle(gpfn_list, trans->gpfn_list);
-            safe_munlock(gpfn_list, trans->nr_gpfns * sizeof(long));
+            safe_munlock(gpfn_list, trans->nr_gpfns * sizeof(xen_pfn_t));
             safe_munlock(trans, sizeof(*trans));
         break;
     }
@@ -263,7 +264,7 @@ long long xc_domain_get_cpu_usage( int x
 
 int xc_get_pfn_list(int xc_handle,
                     uint32_t domid,
-                    unsigned long *pfn_buf,
+                    xen_pfn_t *pfn_buf,
                     unsigned long max_pfns)
 {
     DECLARE_DOM0_OP;
@@ -274,10 +275,10 @@ int xc_get_pfn_list(int xc_handle,
     set_xen_guest_handle(op.u.getmemlist.buffer, pfn_buf);
 
 #ifdef VALGRIND
-    memset(pfn_buf, 0, max_pfns * sizeof(unsigned long));
+    memset(pfn_buf, 0, max_pfns * sizeof(xen_pfn_t));
 #endif
 
-    if ( mlock(pfn_buf, max_pfns * sizeof(unsigned long)) != 0 )
+    if ( mlock(pfn_buf, max_pfns * sizeof(xen_pfn_t)) != 0 )
     {
         PERROR("xc_get_pfn_list: pfn_buf mlock failed");
         return -1;
@@ -285,7 +286,7 @@ int xc_get_pfn_list(int xc_handle,
 
     ret = do_dom0_op(xc_handle, &op);
 
-    safe_munlock(pfn_buf, max_pfns * sizeof(unsigned long));
+    safe_munlock(pfn_buf, max_pfns * sizeof(xen_pfn_t));
 
 #if 0
 #ifdef DEBUG
@@ -293,10 +294,10 @@ int xc_get_pfn_list(int xc_handle,
     if (ret >= 0) {
         int i, j;
         for (i = 0; i < op.u.getmemlist.num_pfns; i += 16) {
-            fprintf(stderr, "0x%x: ", i);
+            DPRINTF("0x%x: ", i);
             for (j = 0; j < 16; j++)
-                fprintf(stderr, "0x%lx ", pfn_buf[i + j]);
-            fprintf(stderr, "\n");
+                DPRINTF("0x%lx ", pfn_buf[i + j]);
+            DPRINTF("\n");
         }
     }
 #endif
@@ -364,7 +365,7 @@ unsigned long xc_get_filesz(int fd)
 }
 
 void xc_map_memcpy(unsigned long dst, const char *src, unsigned long size,
-                   int xch, uint32_t dom, unsigned long *parray,
+                   int xch, uint32_t dom, xen_pfn_t *parray,
                    unsigned long vstart)
 {
     char *va;
@@ -428,6 +429,29 @@ int xc_version(int xc_handle, int cmd, v
         safe_munlock(arg, argsize);
 
     return rc;
+}
+
+unsigned long xc_make_page_below_4G(
+    int xc_handle, uint32_t domid, unsigned long mfn)
+{
+    xen_pfn_t old_mfn = mfn;
+    xen_pfn_t new_mfn;
+
+    if ( xc_domain_memory_decrease_reservation(
+        xc_handle, domid, 1, 0, &old_mfn) != 0 )
+    {
+        DPRINTF("xc_make_page_below_4G decrease failed. mfn=%lx\n",mfn);
+        return 0;
+    }
+
+    if ( xc_domain_memory_increase_reservation(
+        xc_handle, domid, 1, 0, 32, &new_mfn) != 0 )
+    {
+        DPRINTF("xc_make_page_below_4G increase failed. mfn=%lx\n",mfn);
+        return 0;
+    }
+
+    return new_mfn;
 }
 
 /*
diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_private.h
--- a/tools/libxc/xc_private.h  Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/libxc/xc_private.h  Tue Jun 13 12:12:24 2006 -0600
@@ -28,25 +28,50 @@
 #define DECLARE_DOM0_OP dom0_op_t op
 #endif
 
-
 #define PAGE_SHIFT              XC_PAGE_SHIFT
 #define PAGE_SIZE               (1UL << PAGE_SHIFT)
 #define PAGE_MASK               (~(PAGE_SIZE-1))
 
-#define ERROR(_m, _a...)                                \
+#define DEBUG    1
+#define INFO     1
+#define PROGRESS 0
+
+#if INFO
+#define IPRINTF(_f, _a...) printf(_f , ## _a)
+#else
+#define IPRINTF(_f, _a...) ((void)0)
+#endif
+
+#if DEBUG
+#define DPRINTF(_f, _a...) fprintf(stderr, _f , ## _a)
+#else
+#define DPRINTF(_f, _a...) ((void)0)
+#endif
+
+#if PROGRESS
+#define PPRINTF(_f, _a...) fprintf(stderr, _f , ## _a)
+#else
+#define PPRINTF(_f, _a...)
+#endif
+
+#define ERR(_f, _a...) do {                     \
+    DPRINTF(_f ": %d\n" , ## _a, errno);        \
+    fflush(stderr); }                           \
+while (0)
+
+#define ERROR(_m, _a...)                        \
+do {                                            \
+    int __saved_errno = errno;                  \
+    DPRINTF("ERROR: " _m "\n" , ## _a );        \
+    errno = __saved_errno;                      \
+} while (0)
+
+#define PERROR(_m, _a...)                               \
 do {                                                    \
     int __saved_errno = errno;                          \
-    fprintf(stderr, "ERROR: " _m "\n" , ## _a );        \
+    DPRINTF("ERROR: " _m " (%d = %s)\n" , ## _a ,       \
+            __saved_errno, strerror(__saved_errno));    \
     errno = __saved_errno;                              \
-} while (0)
-
-
-#define PERROR(_m, _a...)                                       \
-do {                                                            \
-    int __saved_errno = errno;                                  \
-    fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a ,       \
-            __saved_errno, strerror(__saved_errno));            \
-    errno = __saved_errno;                                      \
 } while (0)
 
 static inline void safe_munlock(const void *addr, size_t len)
@@ -88,7 +113,7 @@ static inline int do_dom0_op(int xc_hand
     if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
     {
         if ( errno == EACCES )
-            fprintf(stderr, "Dom0 operation failed -- need to"
+            DPRINTF("Dom0 operation failed -- need to"
                     " rebuild the user-space tool set?\n");
     }
 
diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_ptrace.c
--- a/tools/libxc/xc_ptrace.c   Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/libxc/xc_ptrace.c   Tue Jun 13 12:12:24 2006 -0600
@@ -143,7 +143,7 @@ online_vcpus_changed(cpumap_t cpumap)
         {
             if (handlers.td_create) handlers.td_create(index - 1);
         } else {
-            printf("thread death: %d\n", index - 1);
+            IPRINTF("thread death: %d\n", index - 1);
             if (handlers.td_death) handlers.td_death(index - 1);
         }
         changed_cpumap &= ~(1 << (index - 1));
@@ -190,7 +190,8 @@ map_domain_va_32(
     static void *v[MAX_VIRT_CPUS];
 
     l2 = xc_map_foreign_range(
-         xc_handle, current_domid, PAGE_SIZE, PROT_READ, ctxt[cpu].ctrlreg[3] 
>> PAGE_SHIFT);
+         xc_handle, current_domid, PAGE_SIZE, PROT_READ,
+         xen_cr3_to_pfn(ctxt[cpu].ctrlreg[3]));
     if ( l2 == NULL )
         return NULL;
 
@@ -230,7 +231,8 @@ map_domain_va_pae(
     static void *v[MAX_VIRT_CPUS];
 
     l3 = xc_map_foreign_range(
-        xc_handle, current_domid, PAGE_SIZE, PROT_READ, ctxt[cpu].ctrlreg[3] 
>> PAGE_SHIFT);
+        xc_handle, current_domid, PAGE_SIZE, PROT_READ,
+        xen_cr3_to_pfn(ctxt[cpu].ctrlreg[3]));
     if ( l3 == NULL )
         return NULL;
 
@@ -282,8 +284,9 @@ map_domain_va_64(
     if ((ctxt[cpu].ctrlreg[4] & 0x20) == 0 ) /* legacy ia32 mode */
         return map_domain_va_32(xc_handle, cpu, guest_va, perm);
 
-    l4 = xc_map_foreign_range( xc_handle, current_domid, PAGE_SIZE,
-            PROT_READ, ctxt[cpu].ctrlreg[3] >> PAGE_SHIFT);
+    l4 = xc_map_foreign_range(
+        xc_handle, current_domid, PAGE_SIZE, PROT_READ,
+        xen_cr3_to_pfn(ctxt[cpu].ctrlreg[3]));
     if ( l4 == NULL )
         return NULL;
 
@@ -365,13 +368,13 @@ map_domain_va(
         nr_pages = npgs;
         if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
         {
-            printf("Could not allocate memory\n");
+            IPRINTF("Could not allocate memory\n");
             return NULL;
         }
         if ( xc_get_pfn_list(xc_handle, current_domid,
                              page_array, nr_pages) != nr_pages )
         {
-            printf("Could not get the page frame list\n");
+            IPRINTF("Could not get the page frame list\n");
             return NULL;
         }
     }
@@ -430,7 +433,7 @@ __xc_waitdomain(
     retval = do_dom0_op(xc_handle, &op);
     if ( retval || (op.u.getdomaininfo.domain != domain) )
     {
-        printf("getdomaininfo failed\n");
+        IPRINTF("getdomaininfo failed\n");
         goto done;
     }
     *status = op.u.getdomaininfo.flags;
@@ -451,7 +454,7 @@ __xc_waitdomain(
     }
  done:
     if (get_online_cpumap(xc_handle, &op.u.getdomaininfo, &cpumap))
-        printf("get_online_cpumap failed\n");
+        IPRINTF("get_online_cpumap failed\n");
     if (online_cpumap != cpumap)
         online_vcpus_changed(cpumap);
     return retval;
@@ -592,7 +595,7 @@ xc_ptrace(
         if ( retval || (op.u.getdomaininfo.domain != current_domid) )
             goto out_error_dom0;
         if ( op.u.getdomaininfo.flags & DOMFLAGS_PAUSED )
-            printf("domain currently paused\n");
+            IPRINTF("domain currently paused\n");
         else if ((retval = xc_domain_pause(xc_handle, current_domid)))
             goto out_error_dom0;
         op.cmd = DOM0_SETDEBUGGING;
@@ -602,7 +605,7 @@ xc_ptrace(
             goto out_error_dom0;
 
         if (get_online_cpumap(xc_handle, &op.u.getdomaininfo, &cpumap))
-            printf("get_online_cpumap failed\n");
+            IPRINTF("get_online_cpumap failed\n");
         if (online_cpumap != cpumap)
             online_vcpus_changed(cpumap);
         break;
@@ -616,7 +619,7 @@ xc_ptrace(
         goto out_unsupported; /* XXX not yet supported */
 
     case PTRACE_TRACEME:
-        printf("PTRACE_TRACEME is an invalid request under Xen\n");
+        IPRINTF("PTRACE_TRACEME is an invalid request under Xen\n");
         goto out_error;
     }
 
@@ -630,7 +633,7 @@ xc_ptrace(
 
  out_unsupported:
 #ifdef DEBUG
-    printf("unsupported xc_ptrace request %s\n", ptrace_names[request]);
+    IPRINTF("unsupported xc_ptrace request %s\n", ptrace_names[request]);
 #endif
     errno = ENOSYS;
     return -1;
diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_ptrace.h
--- a/tools/libxc/xc_ptrace.h   Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/libxc/xc_ptrace.h   Tue Jun 13 12:12:24 2006 -0600
@@ -160,7 +160,6 @@ struct gdb_regs {
 }
 #endif
 
-#define printval(x) printf("%s = %lx\n", #x, (long)x);
 #endif
 
 typedef void (*thr_ev_handler_t)(long);
diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xc_ptrace_core.c
--- a/tools/libxc/xc_ptrace_core.c      Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/libxc/xc_ptrace_core.c      Tue Jun 13 12:12:24 2006 -0600
@@ -12,8 +12,8 @@ static long   nr_pages = 0;
 static long   nr_pages = 0;
 static unsigned long  *p2m_array = NULL;
 static unsigned long  *m2p_array = NULL;
-static unsigned long            pages_offset;
-static unsigned long            cr3[MAX_VIRT_CPUS];
+static unsigned long   pages_offset;
+static unsigned long   cr3[MAX_VIRT_CPUS];
 
 /* --------------------- */
 
@@ -47,7 +47,7 @@ map_domain_va_core(unsigned long domfd, 
             munmap(cr3_virt[cpu], PAGE_SIZE);
         v = mmap(
             NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, domfd,
-            map_mtop_offset(cr3_phys[cpu]));
+            map_mtop_offset(xen_cr3_to_pfn(cr3_phys[cpu])));
         if (v == MAP_FAILED)
         {
             perror("mmap failed");
@@ -85,7 +85,7 @@ map_domain_va_core(unsigned long domfd, 
             map_mtop_offset(page_phys[cpu]));
         if (v == MAP_FAILED)
         {
-            printf("cr3 %lx pde %lx page %lx pti %lx\n", cr3[cpu], pde, page, 
l1_table_offset_i386(va));
+            IPRINTF("cr3 %lx pde %lx page %lx pti %lx\n", cr3[cpu], pde, page, 
l1_table_offset_i386(va));
             page_phys[cpu] = 0;
             return NULL;
         }
@@ -113,7 +113,7 @@ xc_waitdomain_core(
             return -1;
 
         if (header.xch_magic != XC_CORE_MAGIC) {
-                printf("Magic number missmatch: 0x%08x (file) != "
+                IPRINTF("Magic number missmatch: 0x%08x (file) != "
                                         " 0x%08x (code)\n", header.xch_magic,
                                         XC_CORE_MAGIC);
                 return -1;
@@ -127,29 +127,28 @@ xc_waitdomain_core(
             sizeof(vcpu_guest_context_t)*nr_vcpus)
             return -1;
 
-        for (i = 0; i < nr_vcpus; i++) {
+        for (i = 0; i < nr_vcpus; i++)
             cr3[i] = ctxt[i].ctrlreg[3];
-        }
+
         if ((p2m_array = malloc(nr_pages * sizeof(unsigned long))) == NULL)
         {
-            printf("Could not allocate p2m_array\n");
+            IPRINTF("Could not allocate p2m_array\n");
             return -1;
         }
+
         if (read(domfd, p2m_array, sizeof(unsigned long)*nr_pages) !=
             sizeof(unsigned long)*nr_pages)
             return -1;
 
         if ((m2p_array = malloc((1<<20) * sizeof(unsigned long))) == NULL)
         {
-            printf("Could not allocate m2p array\n");
+            IPRINTF("Could not allocate m2p array\n");
             return -1;
         }
         bzero(m2p_array, sizeof(unsigned long)* 1 << 20);
 
-        for (i = 0; i < nr_pages; i++) {
+        for (i = 0; i < nr_pages; i++)
             m2p_array[p2m_array[i]] = i;
-        }
-
     }
     return 0;
 }
diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/libxc/xenctrl.h     Tue Jun 13 12:12:24 2006 -0600
@@ -415,26 +415,26 @@ int xc_domain_memory_increase_reservatio
                                           unsigned long nr_extents,
                                           unsigned int extent_order,
                                           unsigned int address_bits,
-                                          unsigned long *extent_start);
+                                          xen_pfn_t *extent_start);
 
 int xc_domain_memory_decrease_reservation(int xc_handle,
                                           uint32_t domid,
                                           unsigned long nr_extents,
                                           unsigned int extent_order,
-                                          unsigned long *extent_start);
+                                          xen_pfn_t *extent_start);
 
 int xc_domain_memory_populate_physmap(int xc_handle,
                                       uint32_t domid,
                                       unsigned long nr_extents,
                                       unsigned int extent_order,
                                       unsigned int address_bits,
-                                      unsigned long *extent_start);
+                                      xen_pfn_t *extent_start);
 
 int xc_domain_translate_gpfn_list(int xc_handle,
                                   uint32_t domid,
                                   unsigned long nr_gpfns,
-                                  unsigned long *gpfn_list,
-                                  unsigned long *mfn_list);
+                                  xen_pfn_t *gpfn_list,
+                                  xen_pfn_t *mfn_list);
 
 int xc_domain_ioport_permission(int xc_handle,
                                 uint32_t domid,
@@ -453,6 +453,9 @@ int xc_domain_iomem_permission(int xc_ha
                                unsigned long nr_mfns,
                                uint8_t allow_access);
 
+unsigned long xc_make_page_below_4G(int xc_handle, uint32_t domid,
+                                    unsigned long mfn);
+
 typedef dom0_perfc_desc_t xc_perfc_desc_t;
 /* IMPORTANT: The caller is responsible for mlock()'ing the @desc array. */
 int xc_perfc_control(int xc_handle,
@@ -484,7 +487,7 @@ void *xc_map_foreign_range(int xc_handle
                             unsigned long mfn );
 
 void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot,
-                           unsigned long *arr, int num );
+                           xen_pfn_t *arr, int num );
 
 /**
  * Translates a virtual address in the context of a given domain and
@@ -499,11 +502,11 @@ unsigned long xc_translate_foreign_addre
 unsigned long xc_translate_foreign_address(int xc_handle, uint32_t dom,
                                            int vcpu, unsigned long long virt);
 
-int xc_get_pfn_list(int xc_handle, uint32_t domid, unsigned long *pfn_buf,
+int xc_get_pfn_list(int xc_handle, uint32_t domid, xen_pfn_t *pfn_buf,
                     unsigned long max_pfns);
 
 int xc_ia64_get_pfn_list(int xc_handle, uint32_t domid,
-                         unsigned long *pfn_buf,
+                         xen_pfn_t *pfn_buf,
                          unsigned int start_page, unsigned int nr_pages);
 
 int xc_copy_to_domain_page(int xc_handle, uint32_t domid,
diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xg_private.h
--- a/tools/libxc/xg_private.h  Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/libxc/xg_private.h  Tue Jun 13 12:12:24 2006 -0600
@@ -12,6 +12,7 @@
 
 #include "xenctrl.h"
 #include "xenguest.h"
+#include "xc_private.h"
 
 #include <xen/sys/privcmd.h>
 #include <xen/memory.h>
@@ -129,23 +130,6 @@ typedef unsigned long l4_pgentry_t;
   (((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1))
 #endif
 
-#define ERROR(_m, _a...)                                \
-do {                                                    \
-    int __saved_errno = errno;                          \
-    fprintf(stderr, "ERROR: " _m "\n" , ## _a );        \
-    errno = __saved_errno;                              \
-} while (0)
-
-
-#define PERROR(_m, _a...)                                       \
-do {                                                            \
-    int __saved_errno = errno;                                  \
-    fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a ,       \
-            __saved_errno, strerror(__saved_errno));            \
-    errno = __saved_errno;                                      \
-} while (0)
-
-
 struct domain_setup_info
 {
     unsigned long v_start;
@@ -156,6 +140,9 @@ struct domain_setup_info
 
     unsigned long elf_paddr_offset;
 
+#define PAEKERN_no           0
+#define PAEKERN_yes          1
+#define PAEKERN_extended_cr3 2
     unsigned int  pae_kernel;
 
     unsigned int  load_symtab;
@@ -170,7 +157,7 @@ typedef int (*parseimagefunc)(const char
                               struct domain_setup_info *dsi);
 typedef int (*loadimagefunc)(const char *image, unsigned long image_size,
                              int xch,
-                             uint32_t dom, unsigned long *parray,
+                             uint32_t dom, xen_pfn_t *parray,
                              struct domain_setup_info *dsi);
 
 struct load_funcs
@@ -198,7 +185,7 @@ unsigned long xc_get_filesz(int fd);
 unsigned long xc_get_filesz(int fd);
 
 void xc_map_memcpy(unsigned long dst, const char *src, unsigned long size,
-                   int xch, uint32_t dom, unsigned long *parray,
+                   int xch, uint32_t dom, xen_pfn_t *parray,
                    unsigned long vstart);
 
 int pin_table(int xc_handle, unsigned int type, unsigned long mfn,
diff -r b8f6089cbce3 -r e74c47d073ee tools/libxc/xg_save_restore.h
--- a/tools/libxc/xg_save_restore.h     Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/libxc/xg_save_restore.h     Tue Jun 13 12:12:24 2006 -0600
@@ -5,28 +5,6 @@
 */
 
 #include "xc_private.h"
-
-#define DEBUG    1
-#define PROGRESS 0
-
-#define ERR(_f, _a...) do {                     \
-    fprintf(stderr, _f ": %d\n" , ## _a, errno);\
-    fflush(stderr); }                           \
-while (0)
-
-#if DEBUG
-#define DPRINTF(_f, _a...) fprintf(stderr, _f , ## _a)
-#else
-#define DPRINTF(_f, _a...) ((void)0)
-#endif
-
-
-#if PROGRESS
-#define PPRINTF(_f, _a...) fprintf(stderr, _f , ## _a)
-#else
-#define PPRINTF(_f, _a...)
-#endif
-
 
 /*
 ** We process save/restore/migrate in batches of pages; the below
@@ -105,23 +83,23 @@ static int get_platform_info(int xc_hand
 */
 #define M2P_SHIFT       L2_PAGETABLE_SHIFT_PAE
 #define M2P_CHUNK_SIZE  (1 << M2P_SHIFT)
-#define M2P_SIZE(_m)    ROUNDUP(((_m) * sizeof(unsigned long)), M2P_SHIFT)
+#define M2P_SIZE(_m)    ROUNDUP(((_m) * sizeof(xen_pfn_t)), M2P_SHIFT)
 #define M2P_CHUNKS(_m)  (M2P_SIZE((_m)) >> M2P_SHIFT)
 
 /* Size in bytes of the P2M (rounded up to the nearest PAGE_SIZE bytes) */
-#define P2M_SIZE        ROUNDUP((max_pfn * sizeof(unsigned long)), PAGE_SHIFT)
+#define P2M_SIZE        ROUNDUP((max_pfn * sizeof(xen_pfn_t)), PAGE_SHIFT)
 
-/* Number of unsigned longs in a page */
-#define ulpp            (PAGE_SIZE/sizeof(unsigned long))
+/* Number of xen_pfn_t in a page */
+#define fpp             (PAGE_SIZE/sizeof(xen_pfn_t))
 
 /* Number of entries in the pfn_to_mfn_frame_list */
-#define P2M_FL_ENTRIES  (((max_pfn)+ulpp-1)/ulpp)
+#define P2M_FL_ENTRIES  (((max_pfn)+fpp-1)/fpp)
 
 /* Size in bytes of the pfn_to_mfn_frame_list     */
 #define P2M_FL_SIZE     ((P2M_FL_ENTRIES)*sizeof(unsigned long))
 
 /* Number of entries in the pfn_to_mfn_frame_list_list */
-#define P2M_FLL_ENTRIES (((max_pfn)+(ulpp*ulpp)-1)/(ulpp*ulpp))
+#define P2M_FLL_ENTRIES (((max_pfn)+(fpp*fpp)-1)/(fpp*fpp))
 
 /* Current guests allow 8MB 'slack' in their P2M */
 #define NR_SLACK_ENTRIES   ((8 * 1024 * 1024) / PAGE_SIZE)
diff -r b8f6089cbce3 -r e74c47d073ee tools/python/xen/lowlevel/acm/acm.c
--- a/tools/python/xen/lowlevel/acm/acm.c       Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/python/xen/lowlevel/acm/acm.c       Tue Jun 13 12:12:24 2006 -0600
@@ -52,9 +52,9 @@ void * __getssid(int domid, uint32_t *bu
     }
     memset(buf, 0, SSID_BUFFER_SIZE);
     getssid.interface_version = ACM_INTERFACE_VERSION;
-    getssid.ssidbuf = buf;
+    set_xen_guest_handle(getssid.ssidbuf, buf);
     getssid.ssidbuf_size = SSID_BUFFER_SIZE;
-    getssid.get_ssid_by = DOMAINID;
+    getssid.get_ssid_by = ACM_GETBY_domainid;
     getssid.id.domainid = domid;
 
     if (xc_acm_op(xc_handle, ACMOP_getssid, &getssid, sizeof(getssid)) < 0) {
@@ -163,19 +163,19 @@ static PyObject *getdecision(PyObject * 
         return NULL;
 
     getdecision.interface_version = ACM_INTERFACE_VERSION;
-    getdecision.hook = SHARING;
+    getdecision.hook = ACMHOOK_sharing;
     if (!strcmp(arg1_name, "domid")) {
-        getdecision.get_decision_by1 = DOMAINID;
+        getdecision.get_decision_by1 = ACM_GETBY_domainid;
         getdecision.id1.domainid = atoi(arg1);
     } else {
-        getdecision.get_decision_by1 = SSIDREF;
+        getdecision.get_decision_by1 = ACM_GETBY_ssidref;
         getdecision.id1.ssidref = atol(arg1);
     }
     if (!strcmp(arg2_name, "domid")) {
-        getdecision.get_decision_by2 = DOMAINID;
+        getdecision.get_decision_by2 = ACM_GETBY_domainid;
         getdecision.id2.domainid = atoi(arg2);
     } else {
-        getdecision.get_decision_by2 = SSIDREF;
+        getdecision.get_decision_by2 = ACM_GETBY_ssidref;
         getdecision.id2.ssidref = atol(arg2);
     }
 
diff -r b8f6089cbce3 -r e74c47d073ee tools/python/xen/lowlevel/xs/xs.c
--- a/tools/python/xen/lowlevel/xs/xs.c Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/python/xen/lowlevel/xs/xs.c Tue Jun 13 12:12:24 2006 -0600
@@ -28,6 +28,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <errno.h>
 
 #include <xenctrl.h>
 #include "xs.h"
@@ -43,6 +44,8 @@
 
 #define PKG "xen.lowlevel.xs"
 #define CLS "xs"
+
+static PyObject *xs_error;
 
 /** Python wrapper round an xs handle.
  */
@@ -52,11 +55,17 @@ typedef struct XsHandle {
     PyObject *watches;
 } XsHandle;
 
+static void xs_set_error(int value)
+{
+       errno = value;
+       PyErr_SetFromErrno(xs_error);
+}
+
 static inline struct xs_handle *xshandle(XsHandle *self)
 {
     struct xs_handle *xh = self->xh;
     if (!xh)
-        PyErr_SetString(PyExc_RuntimeError, "invalid xenstore daemon handle");
+       xs_set_error(EINVAL);
     return xh;
 }
 
@@ -77,7 +86,7 @@ static int parse_transaction_path(XsHand
        "\n"                                            \
        "Returns: [string] data read.\n"                \
        "         None if key doesn't exist.\n"         \
-       "Raises RuntimeError on error.\n"               \
+       "Raises xen.lowlevel.xs.Error on error.\n"               \
        "\n"
 
 static PyObject *xspy_read(XsHandle *self, PyObject *args)
@@ -113,7 +122,7 @@ static PyObject *xspy_read(XsHandle *sel
        " data   [string] : data to write.\n"                   \
        "\n"                                                    \
        "Returns None on success.\n"                            \
-       "Raises RuntimeError on error.\n"                       \
+       "Raises xen.lowlevel.xs.Error on error.\n"                      \
        "\n"
 
 static PyObject *xspy_write(XsHandle *self, PyObject *args)
@@ -149,7 +158,7 @@ static PyObject *xspy_write(XsHandle *se
        "\n"                                                    \
        "Returns: [string array] list of subdirectory names.\n" \
        "         None if key doesn't exist.\n"                 \
-       "Raises RuntimeError on error.\n"                       \
+       "Raises xen.lowlevel.xs.Error on error.\n"                      \
        "\n"
 
 static PyObject *xspy_ls(XsHandle *self, PyObject *args)
@@ -187,7 +196,7 @@ static PyObject *xspy_ls(XsHandle *self,
        " path [string]: path to directory to create.\n"        \
        "\n"                                                    \
        "Returns None on success.\n"                            \
-       "Raises RuntimeError on error.\n"                       \
+       "Raises xen.lowlevel.xs.Error on error.\n"                      \
        "\n"
 
 static PyObject *xspy_mkdir(XsHandle *self, PyObject *args)
@@ -215,7 +224,7 @@ static PyObject *xspy_mkdir(XsHandle *se
        " path [string] : path to remove\n"             \
        "\n"                                            \
        "Returns None on success.\n"                    \
-       "Raises RuntimeError on error.\n"               \
+       "Raises xen.lowlevel.xs.Error on error.\n"               \
        "\n"
 
 static PyObject *xspy_rm(XsHandle *self, PyObject *args)
@@ -243,7 +252,7 @@ static PyObject *xspy_rm(XsHandle *self,
        " path [string]:        xenstore path.\n"       \
        "\n"                                            \
        "Returns: permissions array.\n"                 \
-       "Raises RuntimeError on error.\n"               \
+       "Raises xen.lowlevel.xs.Error on error.\n"               \
        "\n"
 
 static PyObject *xspy_get_permissions(XsHandle *self, PyObject *args)
@@ -285,7 +294,7 @@ static PyObject *xspy_get_permissions(Xs
         return val;
     }
     else {
-        PyErr_SetFromErrno(PyExc_RuntimeError);
+        PyErr_SetFromErrno(xs_error);
         return NULL;
     }
 }
@@ -297,7 +306,7 @@ static PyObject *xspy_get_permissions(Xs
        " perms               : permissions.\n"         \
        "\n"                                            \
        "Returns None on success.\n"                    \
-       "Raises RuntimeError on error.\n"               \
+       "Raises xen.lowlevel.xs.Error on error.\n"               \
        "\n"
 
 static PyObject *xspy_set_permissions(XsHandle *self, PyObject *args)
@@ -324,13 +333,13 @@ static PyObject *xspy_set_permissions(Xs
     th = strtoul(thstr, NULL, 16);
 
     if (!PyList_Check(perms)) {
-        PyErr_SetString(PyExc_RuntimeError, "perms must be a list");
+       xs_set_error(EINVAL);
         goto exit;
     }
     xsperms_n = PyList_Size(perms);
     xsperms = calloc(xsperms_n, sizeof(struct xs_permissions));
     if (!xsperms) {
-        PyErr_SetString(PyExc_RuntimeError, "out of memory");
+       xs_set_error(ENOMEM);
         goto exit;
     }
     tuple0 = PyTuple_New(0);
@@ -352,7 +361,7 @@ static PyObject *xspy_set_permissions(Xs
     result = xs_set_permissions(xh, th, path, xsperms, xsperms_n);
     Py_END_ALLOW_THREADS
     if (!result) {
-        PyErr_SetFromErrno(PyExc_RuntimeError);
+        PyErr_SetFromErrno(xs_error);
         goto exit;
     }
 
@@ -371,7 +380,7 @@ static PyObject *xspy_set_permissions(Xs
        " token    [string] : returned in watch notification.\n"        \
        "\n"                                                            \
        "Returns None on success.\n"                                    \
-       "Raises RuntimeError on error.\n"                               \
+       "Raises xen.lowlevel.xs.Error on error.\n"                              
\
        "\n"
 
 /* Each 10 bits takes ~ 3 digits, plus one, plus one for nul terminator. */
@@ -421,7 +430,7 @@ static PyObject *xspy_watch(XsHandle *se
        "Read a watch notification.\n"                          \
        "\n"                                                    \
        "Returns: [tuple] (path, token).\n"                     \
-       "Raises RuntimeError on error.\n"                       \
+       "Raises xen.lowlevel.xs.Error on error.\n"                      \
        "\n"
 
 static PyObject *xspy_read_watch(XsHandle *self, PyObject *args)
@@ -441,11 +450,11 @@ again:
     xsval = xs_read_watch(xh, &num);
     Py_END_ALLOW_THREADS
     if (!xsval) {
-        PyErr_SetFromErrno(PyExc_RuntimeError);
+        PyErr_SetFromErrno(xs_error);
         goto exit;
     }
     if (sscanf(xsval[XS_WATCH_TOKEN], "%li", (unsigned long *)&token) != 1) {
-        PyErr_SetString(PyExc_RuntimeError, "invalid token");
+       xs_set_error(EINVAL);
         goto exit;
     }
     for (i = 0; i < PyList_Size(self->watches); i++) {
@@ -474,7 +483,7 @@ again:
        " token [string] : token from the watch.\n"     \
        "\n"                                            \
        "Returns None on success.\n"                    \
-       "Raises RuntimeError on error.\n"               \
+       "Raises xen.lowlevel.xs.Error on error.\n"              \
        "\n"
 
 static PyObject *xspy_unwatch(XsHandle *self, PyObject *args)
@@ -504,7 +513,7 @@ static PyObject *xspy_unwatch(XsHandle *
        "Start a transaction.\n"                                \
        "\n"                                                    \
        "Returns transaction handle on success.\n"              \
-       "Raises RuntimeError on error.\n"                       \
+       "Raises xen.lowlevel.xs.Error on error.\n"                      \
        "\n"
 
 static PyObject *xspy_transaction_start(XsHandle *self)
@@ -521,7 +530,7 @@ static PyObject *xspy_transaction_start(
     Py_END_ALLOW_THREADS
 
     if (th == XBT_NULL) {
-        PyErr_SetFromErrno(PyExc_RuntimeError);
+        PyErr_SetFromErrno(xs_error);
         return NULL;
     }
 
@@ -535,7 +544,7 @@ static PyObject *xspy_transaction_start(
        " abort [int]: abort flag (default 0).\n"                       \
        "\n"                                                            \
        "Returns True on success, False if you need to try again.\n"    \
-       "Raises RuntimeError on error.\n"                               \
+       "Raises xen.lowlevel.xs.Error on error.\n"                              
\
        "\n"
 
 static PyObject *xspy_transaction_end(XsHandle *self, PyObject *args,
@@ -572,7 +581,7 @@ static PyObject *xspy_transaction_end(Xs
         return Py_False;
     }
     else {
-        PyErr_SetFromErrno(PyExc_RuntimeError);
+        PyErr_SetFromErrno(xs_error);
         return NULL;
     }
 }
@@ -585,7 +594,7 @@ static PyObject *xspy_transaction_end(Xs
        " port [int]   : port the domain is using for xenstore\n"       \
        "\n"                                                            \
        "Returns None on success.\n"                                    \
-       "Raises RuntimeError on error.\n"                               \
+       "Raises xen.lowlevel.xs.Error on error.\n"                              
\
        "\n"
 
 static PyObject *xspy_introduce_domain(XsHandle *self, PyObject *args)
@@ -616,7 +625,7 @@ static PyObject *xspy_introduce_domain(X
        " dom [int]: domain id\n"                                       \
        "\n"                                                            \
        "Returns None on success.\n"                                    \
-       "Raises RuntimeError on error.\n"                               \
+       "Raises xen.lowlevel.xs.Error on error.\n"                              
\
        "\n"
 
 static PyObject *xspy_release_domain(XsHandle *self, PyObject *args)
@@ -643,7 +652,7 @@ static PyObject *xspy_release_domain(XsH
        "Close the connection to xenstore.\n"   \
        "\n"                                    \
        "Returns None on success.\n"            \
-       "Raises RuntimeError on error.\n"       \
+       "Raises xen.lowlevel.xs.Error on error.\n"      \
        "\n"
 
 static PyObject *xspy_close(XsHandle *self)
@@ -672,7 +681,7 @@ static PyObject *xspy_close(XsHandle *se
        " domid [int]: domain id\n"                     \
        "\n"                                            \
        "Returns: [string] domain store path.\n"        \
-       "Raises RuntimeError on error.\n"               \
+       "Raises xen.lowlevel.xs.Error on error.\n"              \
        "\n"
 
 static PyObject *xspy_get_domain_path(XsHandle *self, PyObject *args)
@@ -754,7 +763,7 @@ static PyObject *none(bool result)
         return Py_None;
     }
     else {
-        PyErr_SetFromErrno(PyExc_RuntimeError);
+        PyErr_SetFromErrno(xs_error);
         return NULL;
     }
 }
@@ -830,7 +839,7 @@ xshandle_init(XsHandle *self, PyObject *
     return 0;
 
  fail:
-    PyErr_SetFromErrno(PyExc_RuntimeError);
+    PyErr_SetFromErrno(xs_error);
     return -1;
 }
 
@@ -902,8 +911,13 @@ PyMODINIT_FUNC initxs(void)
     if (m == NULL)
       return;
 
+    xs_error = PyErr_NewException(PKG ".Error", PyExc_RuntimeError, NULL);
+
     Py_INCREF(&xshandle_type);
     PyModule_AddObject(m, CLS, (PyObject *)&xshandle_type);
+
+    Py_INCREF(xs_error);
+    PyModule_AddObject(m, "Error", xs_error);
 }
 
 
diff -r b8f6089cbce3 -r e74c47d073ee tools/python/xen/util/security.py
--- a/tools/python/xen/util/security.py Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/python/xen/util/security.py Tue Jun 13 12:12:24 2006 -0600
@@ -426,6 +426,15 @@ def get_decision(arg1, arg2):
             err("Argument type not supported.")
         ssidref = label2ssidref(arg2[2][1], arg2[1][1])
         arg2 = ['ssidref', str(ssidref)]
+
+    # accept only int or string types for domid and ssidref
+    if isinstance(arg1[1], int):
+        arg1[1] = str(arg1[1])
+    if isinstance(arg2[1], int):
+        arg2[1] = str(arg2[1])
+    if not isinstance(arg1[1], str) or not isinstance(arg2[1], str):
+        err("Invalid id or ssidref type, string or int required")
+
     try:
         decision = acm.getdecision(arg1[0], arg1[1], arg2[0], arg2[1])
     except:
diff -r b8f6089cbce3 -r e74c47d073ee tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/python/xen/xend/image.py    Tue Jun 13 12:12:24 2006 -0600
@@ -249,7 +249,8 @@ class HVMImageHandler(ImageHandler):
     # xm config file
     def parseDeviceModelArgs(self, imageConfig, deviceConfig):
         dmargs = [ 'cdrom', 'boot', 'fda', 'fdb', 'ne2000', 'audio',
-                   'localtime', 'serial', 'stdvga', 'isa', 'vcpus']
+                   'localtime', 'serial', 'stdvga', 'isa', 'vcpus',
+                  'usb', 'usbdevice']
         ret = []
         for a in dmargs:
             v = sxp.child_value(imageConfig, a)
@@ -260,7 +261,7 @@ class HVMImageHandler(ImageHandler):
             if a == 'audio': a = 'enable-audio'
 
             # Handle booleans gracefully
-            if a in ['localtime', 'std-vga', 'isa', 'nic-ne2000', 
'enable-audio']:
+            if a in ['localtime', 'std-vga', 'isa', 'nic-ne2000', 
'enable-audio', 'usb']:
                 if v != None: v = int(v)
                 if v: ret.append("-%s" % a)
             else:
diff -r b8f6089cbce3 -r e74c47d073ee tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/python/xen/xm/create.py     Tue Jun 13 12:12:24 2006 -0600
@@ -264,7 +264,7 @@ gopts.var('irq', val='IRQ',
          For example 'irq=7'.
          This option may be repeated to add more than one IRQ.""")
 
-gopts.var('usb', val='PATH',
+gopts.var('usbport', val='PATH',
           fn=append_value, default=[],
           use="""Add a physical USB port to a domain, as specified by the path
           to that port.  This option may be repeated to add more than one 
port.""")
@@ -371,6 +371,14 @@ gopts.var('localtime', val='no|yes',
 gopts.var('localtime', val='no|yes',
           fn=set_bool, default=0,
           use="Is RTC set to localtime?")
+
+gopts.var('usb', val='no|yes',
+          fn=set_bool, default=0,
+          use="Emulate USB devices?")
+
+gopts.var('usbdevice', val='NAME',
+          fn=set_value, default='',
+          use="Name of USB device to add?")
 
 gopts.var('stdvga', val='no|yes',
           fn=set_bool, default=0,
@@ -508,8 +516,8 @@ def configure_irq(config_devs, vals):
         config_devs.append(['device', config_irq])
 
 def configure_usb(config_devs, vals):
-    for path in vals.usb:
-        config_usb = ['usb', ['path', path]]
+    for path in vals.usbport:
+        config_usb = ['usbport', ['path', path]]
         config_devs.append(['device', config_usb])
 
 
@@ -614,7 +622,7 @@ def configure_hvm(config_image, vals):
     args = [ 'device_model', 'pae', 'vcpus', 'cdrom', 'boot', 'fda', 'fdb',
              'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'audio',
              'vnc', 'vncviewer', 'sdl', 'display', 'ne2000', 'acpi', 'apic',
-             'xauthority' ]
+             'xauthority', 'usb', 'usbdevice' ]
     for a in args:
         if (vals.__dict__[a]):
             config_image.append([a, vals.__dict__[a]])
@@ -903,10 +911,15 @@ def make_domain(opts, config):
         else:
             err("%s" % ex.faultString)
     except Exception, ex:
+        # main.py has good error messages that let the user know what failed.
+        # unless the error is a create.py specific thing, it should be handled
+        # at main. The purpose of this general-case 'Exception' handler is to
+        # clean up create.py specific processes/data but since create.py does
+        # not know what to do with the error, it should pass it up.
         import signal
         if vncpid:
             os.kill(vncpid, signal.SIGKILL)
-        err(str(ex))
+        raise ex
 
     dom = sxp.child_value(dominfo, 'name')
 
diff -r b8f6089cbce3 -r e74c47d073ee tools/tests/test_x86_emulator.c
--- a/tools/tests/test_x86_emulator.c   Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/tests/test_x86_emulator.c   Tue Jun 13 12:12:24 2006 -0600
@@ -13,6 +13,7 @@ typedef int64_t            s64;
 typedef int64_t            s64;
 #include <public/xen.h>
 #include <asm-x86/x86_emulate.h>
+#include <sys/mman.h>
 
 static int read_any(
     unsigned long addr,
@@ -85,23 +86,30 @@ int main(int argc, char **argv)
     struct x86_emulate_ctxt ctxt;
     struct cpu_user_regs regs;
     char instr[20] = { 0x01, 0x08 }; /* add %ecx,(%eax) */
-    unsigned int res = 0x7FFFFFFF;
-    u32 cmpxchg8b_res[2] = { 0x12345678, 0x87654321 };
+    unsigned int *res;
     int rc;
 
     ctxt.regs = &regs;
     ctxt.mode = X86EMUL_MODE_PROT32;
 
+    res = mmap((void *)0x100000, 0x1000, PROT_READ|PROT_WRITE,
+               MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
+    if ( res == MAP_FAILED )
+    {
+        fprintf(stderr, "mmap to low address failed\n");
+        exit(1);
+    }
+
     printf("%-40s", "Testing addl %%ecx,(%%eax)...");
     instr[0] = 0x01; instr[1] = 0x08;
     regs.eflags = 0x200;
     regs.eip    = (unsigned long)&instr[0];
     regs.ecx    = 0x12345678;
-    ctxt.cr2    = (unsigned long)&res;
-    res         = 0x7FFFFFFF;
-    rc = x86_emulate_memop(&ctxt, &emulops);
-    if ( (rc != 0) || 
-         (res != 0x92345677) || 
+    ctxt.cr2    = (unsigned long)res;
+    *res        = 0x7FFFFFFF;
+    rc = x86_emulate_memop(&ctxt, &emulops);
+    if ( (rc != 0) || 
+         (*res != 0x92345677) || 
          (regs.eflags != 0xa94) ||
          (regs.eip != (unsigned long)&instr[2]) )
         goto fail;
@@ -116,11 +124,25 @@ int main(int argc, char **argv)
 #else
     regs.ecx    = 0x12345678UL;
 #endif
-    ctxt.cr2    = (unsigned long)&res;
-    rc = x86_emulate_memop(&ctxt, &emulops);
-    if ( (rc != 0) || 
-         (res != 0x92345677) || 
+    ctxt.cr2    = (unsigned long)res;
+    rc = x86_emulate_memop(&ctxt, &emulops);
+    if ( (rc != 0) || 
+         (*res != 0x92345677) || 
          (regs.ecx != 0x8000000FUL) ||
+         (regs.eip != (unsigned long)&instr[2]) )
+        goto fail;
+    printf("okay\n");
+
+    printf("%-40s", "Testing movl (%%eax),%%ecx...");
+    instr[0] = 0x8b; instr[1] = 0x08;
+    regs.eflags = 0x200;
+    regs.eip    = (unsigned long)&instr[0];
+    regs.ecx    = ~0UL;
+    ctxt.cr2    = (unsigned long)res;
+    rc = x86_emulate_memop(&ctxt, &emulops);
+    if ( (rc != 0) || 
+         (*res != 0x92345677) || 
+         (regs.ecx != 0x92345677UL) ||
          (regs.eip != (unsigned long)&instr[2]) )
         goto fail;
     printf("okay\n");
@@ -131,10 +153,10 @@ int main(int argc, char **argv)
     regs.eip    = (unsigned long)&instr[0];
     regs.eax    = 0x92345677UL;
     regs.ecx    = 0xAA;
-    ctxt.cr2    = (unsigned long)&res;
-    rc = x86_emulate_memop(&ctxt, &emulops);
-    if ( (rc != 0) || 
-         (res != 0x923456AA) || 
+    ctxt.cr2    = (unsigned long)res;
+    rc = x86_emulate_memop(&ctxt, &emulops);
+    if ( (rc != 0) || 
+         (*res != 0x923456AA) || 
          (regs.eflags != 0x244) ||
          (regs.eax != 0x92345677UL) ||
          (regs.eip != (unsigned long)&instr[4]) )
@@ -147,10 +169,10 @@ int main(int argc, char **argv)
     regs.eip    = (unsigned long)&instr[0];
     regs.eax    = 0xAABBCC77UL;
     regs.ecx    = 0xFF;
-    ctxt.cr2    = (unsigned long)&res;
-    rc = x86_emulate_memop(&ctxt, &emulops);
-    if ( (rc != 0) || 
-         (res != 0x923456AA) || 
+    ctxt.cr2    = (unsigned long)res;
+    rc = x86_emulate_memop(&ctxt, &emulops);
+    if ( (rc != 0) || 
+         (*res != 0x923456AA) || 
          ((regs.eflags&0x240) != 0x200) ||
          (regs.eax != 0xAABBCCAA) ||
          (regs.ecx != 0xFF) ||
@@ -163,10 +185,10 @@ int main(int argc, char **argv)
     regs.eflags = 0x200;
     regs.eip    = (unsigned long)&instr[0];
     regs.ecx    = 0x12345678;
-    ctxt.cr2    = (unsigned long)&res;
-    rc = x86_emulate_memop(&ctxt, &emulops);
-    if ( (rc != 0) || 
-         (res != 0x12345678) || 
+    ctxt.cr2    = (unsigned long)res;
+    rc = x86_emulate_memop(&ctxt, &emulops);
+    if ( (rc != 0) || 
+         (*res != 0x12345678) || 
          (regs.eflags != 0x200) ||
          (regs.ecx != 0x923456AA) ||
          (regs.eip != (unsigned long)&instr[2]) )
@@ -176,14 +198,14 @@ int main(int argc, char **argv)
     printf("%-40s", "Testing lock cmpxchgl %%ecx,(%%eax)...");
     instr[0] = 0xf0; instr[1] = 0x0f; instr[2] = 0xb1; instr[3] = 0x08;
     regs.eflags = 0x200;
-    res         = 0x923456AA;
+    *res        = 0x923456AA;
     regs.eip    = (unsigned long)&instr[0];
     regs.eax    = 0x923456AAUL;
     regs.ecx    = 0xDDEEFF00L;
-    ctxt.cr2    = (unsigned long)&res;
-    rc = x86_emulate_memop(&ctxt, &emulops);
-    if ( (rc != 0) || 
-         (res != 0xDDEEFF00) || 
+    ctxt.cr2    = (unsigned long)res;
+    rc = x86_emulate_memop(&ctxt, &emulops);
+    if ( (rc != 0) || 
+         (*res != 0xDDEEFF00) || 
          (regs.eflags != 0x244) ||
          (regs.eax != 0x923456AAUL) ||
          (regs.eip != (unsigned long)&instr[4]) )
@@ -192,54 +214,57 @@ int main(int argc, char **argv)
 
     printf("%-40s", "Testing rep movsw...");
     instr[0] = 0xf3; instr[1] = 0x66; instr[2] = 0xa5;
-    res         = 0x22334455;
+    *res        = 0x22334455;
     regs.eflags = 0x200;
     regs.ecx    = 23;
     regs.eip    = (unsigned long)&instr[0];
-    regs.esi    = (unsigned long)&res + 0;
-    regs.edi    = (unsigned long)&res + 2;
+    regs.esi    = (unsigned long)res + 0;
+    regs.edi    = (unsigned long)res + 2;
     regs.error_code = 0; /* read fault */
     ctxt.cr2    = regs.esi;
     rc = x86_emulate_memop(&ctxt, &emulops);
     if ( (rc != 0) || 
-         (res != 0x44554455) ||
+         (*res != 0x44554455) ||
          (regs.eflags != 0x200) ||
          (regs.ecx != 22) || 
-         (regs.esi != ((unsigned long)&res + 2)) ||
-         (regs.edi != ((unsigned long)&res + 4)) ||
+         (regs.esi != ((unsigned long)res + 2)) ||
+         (regs.edi != ((unsigned long)res + 4)) ||
          (regs.eip != (unsigned long)&instr[0]) )
         goto fail;
     printf("okay\n");
 
     printf("%-40s", "Testing btrl $0x1,(%edi)...");
     instr[0] = 0x0f; instr[1] = 0xba; instr[2] = 0x37; instr[3] = 0x01;
-    res         = 0x2233445F;
-    regs.eflags = 0x200;
-    regs.eip    = (unsigned long)&instr[0];
-    regs.edi    = (unsigned long)&res;
+    *res        = 0x2233445F;
+    regs.eflags = 0x200;
+    regs.eip    = (unsigned long)&instr[0];
+    regs.edi    = (unsigned long)res;
     ctxt.cr2    = regs.edi;
     rc = x86_emulate_memop(&ctxt, &emulops);
     if ( (rc != 0) || 
-         (res != 0x2233445D) ||
+         (*res != 0x2233445D) ||
          ((regs.eflags&0x201) != 0x201) ||
          (regs.eip != (unsigned long)&instr[4]) )
         goto fail;
     printf("okay\n");
+
+    res[0] = 0x12345678;
+    res[1] = 0x87654321;
 
     printf("%-40s", "Testing cmpxchg8b (%edi) [succeeding]...");
     instr[0] = 0x0f; instr[1] = 0xc7; instr[2] = 0x0f;
     regs.eflags = 0x200;
-    regs.eax    = cmpxchg8b_res[0];
-    regs.edx    = cmpxchg8b_res[1];
+    regs.eax    = res[0];
+    regs.edx    = res[1];
     regs.ebx    = 0x9999AAAA;
     regs.ecx    = 0xCCCCFFFF;
     regs.eip    = (unsigned long)&instr[0];
-    regs.edi    = (unsigned long)cmpxchg8b_res;
+    regs.edi    = (unsigned long)res;
     ctxt.cr2    = regs.edi;
     rc = x86_emulate_memop(&ctxt, &emulops);
     if ( (rc != 0) || 
-         (cmpxchg8b_res[0] != 0x9999AAAA) ||
-         (cmpxchg8b_res[1] != 0xCCCCFFFF) ||
+         (res[0] != 0x9999AAAA) ||
+         (res[1] != 0xCCCCFFFF) ||
          ((regs.eflags&0x240) != 0x240) ||
          (regs.eip != (unsigned long)&instr[3]) )
         goto fail;
@@ -248,12 +273,12 @@ int main(int argc, char **argv)
     printf("%-40s", "Testing cmpxchg8b (%edi) [failing]...");
     instr[0] = 0x0f; instr[1] = 0xc7; instr[2] = 0x0f;
     regs.eip    = (unsigned long)&instr[0];
-    regs.edi    = (unsigned long)cmpxchg8b_res;
+    regs.edi    = (unsigned long)res;
     ctxt.cr2    = regs.edi;
     rc = x86_emulate_memop(&ctxt, &emulops);
     if ( (rc != 0) || 
-         (cmpxchg8b_res[0] != 0x9999AAAA) ||
-         (cmpxchg8b_res[1] != 0xCCCCFFFF) ||
+         (res[0] != 0x9999AAAA) ||
+         (res[1] != 0xCCCCFFFF) ||
          (regs.eax != 0x9999AAAA) ||
          (regs.edx != 0xCCCCFFFF) ||
          ((regs.eflags&0x240) != 0x200) ||
@@ -265,11 +290,11 @@ int main(int argc, char **argv)
     instr[0] = 0x0f; instr[1] = 0xbe; instr[2] = 0x08;
     regs.eip    = (unsigned long)&instr[0];
     regs.ecx    = 0x12345678;
-    ctxt.cr2    = (unsigned long)&res;
-    res         = 0x82;
+    ctxt.cr2    = (unsigned long)res;
+    *res        = 0x82;
     rc = x86_emulate_memop(&ctxt, &emulops);
     if ( (rc != 0) ||
-         (res != 0x82) ||
+         (*res != 0x82) ||
          (regs.ecx != 0xFFFFFF82) ||
          ((regs.eflags&0x240) != 0x200) ||
          (regs.eip != (unsigned long)&instr[3]) )
@@ -280,11 +305,11 @@ int main(int argc, char **argv)
     instr[0] = 0x0f; instr[1] = 0xb7; instr[2] = 0x08;
     regs.eip    = (unsigned long)&instr[0];
     regs.ecx    = 0x12345678;
-    ctxt.cr2    = (unsigned long)&res;
-    res         = 0x1234aa82;
+    ctxt.cr2    = (unsigned long)res;
+    *res        = 0x1234aa82;
     rc = x86_emulate_memop(&ctxt, &emulops);
     if ( (rc != 0) ||
-         (res != 0x1234aa82) ||
+         (*res != 0x1234aa82) ||
          (regs.ecx != 0xaa82) ||
          ((regs.eflags&0x240) != 0x200) ||
          (regs.eip != (unsigned long)&instr[3]) )
diff -r b8f6089cbce3 -r e74c47d073ee tools/xm-test/configure.ac
--- a/tools/xm-test/configure.ac        Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/xm-test/configure.ac        Tue Jun 13 12:12:24 2006 -0600
@@ -1,7 +1,7 @@
 # xm-test configure.ac input script
 
 # Basic header information
-AC_INIT([xm-test], [0.7.1])
+AC_INIT([xm-test], [0.8.0])
 AM_INIT_AUTOMAKE([1.7 foreign])
 
 # Check for dependencies
@@ -118,6 +118,7 @@ AC_CONFIG_FILES([
     tests/reboot/Makefile
     tests/restore/Makefile
     tests/save/Makefile
+    tests/sched-credit/Makefile
     tests/sedf/Makefile
     tests/shutdown/Makefile
     tests/sysrq/Makefile
diff -r b8f6089cbce3 -r e74c47d073ee tools/xm-test/grouptest/default
--- a/tools/xm-test/grouptest/default   Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/xm-test/grouptest/default   Tue Jun 13 12:12:24 2006 -0600
@@ -1,6 +1,7 @@ block-create
 block-create
 block-destroy
 block-list
+block-integrity
 console
 create
 destroy
diff -r b8f6089cbce3 -r e74c47d073ee tools/xm-test/ramdisk/Makefile.am
--- a/tools/xm-test/ramdisk/Makefile.am Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/xm-test/ramdisk/Makefile.am Tue Jun 13 12:12:24 2006 -0600
@@ -2,7 +2,7 @@ INITRD ?= http://xm-test.xensource.com/r
 
 EXTRA_DIST = skel configs patches
 
-BR_TAR = buildroot-20060427.tar.bz2
+BR_TAR = buildroot-20060606.tar.bz2
 BR_URL = http://buildroot.uclibc.org/downloads/snapshots/$(BR_TAR)
 #BR_URL = 
http://buildroot.uclibc.org/downloads/snapshots/buildroot-snapshot.tar.bz2
 BR_SRC = buildroot
diff -r b8f6089cbce3 -r e74c47d073ee tools/xm-test/ramdisk/configs/busybox
--- a/tools/xm-test/ramdisk/configs/busybox     Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/xm-test/ramdisk/configs/busybox     Tue Jun 13 12:12:24 2006 -0600
@@ -127,8 +127,8 @@ CONFIG_SYNC=y
 CONFIG_SYNC=y
 CONFIG_TAIL=y
 CONFIG_FEATURE_FANCY_TAIL=n
-CONFIG_TEE=n
-CONFIG_FEATURE_TEE_USE_BLOCK_IO=n
+CONFIG_TEE=y
+CONFIG_FEATURE_TEE_USE_BLOCK_IO=y
 CONFIG_TEST=y
 
 #
diff -r b8f6089cbce3 -r e74c47d073ee tools/xm-test/tests/Makefile.am
--- a/tools/xm-test/tests/Makefile.am   Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/xm-test/tests/Makefile.am   Tue Jun 13 12:12:24 2006 -0600
@@ -18,6 +18,7 @@ SUBDIRS =                     \
                network-attach  \
                pause           \
                reboot          \
+               sched-credit    \
                sedf            \
                shutdown        \
                sysrq           \
diff -r b8f6089cbce3 -r e74c47d073ee 
tools/xm-test/tests/block-integrity/Makefile.am
--- a/tools/xm-test/tests/block-integrity/Makefile.am   Tue Jun 13 09:00:32 
2006 -0600
+++ b/tools/xm-test/tests/block-integrity/Makefile.am   Tue Jun 13 12:12:24 
2006 -0600
@@ -1,7 +1,8 @@
 
 SUBDIRS =
 
-TESTS = 01_block_device_read_verify.test
+TESTS = 01_block_device_read_verify.test \
+        02_block_device_write_verify.test
 
 XFAIL_TESTS = 
 
diff -r b8f6089cbce3 -r e74c47d073ee 
tools/xm-test/tests/enforce_dom0_cpus/01_enforce_dom0_cpus_basic_pos.py
--- a/tools/xm-test/tests/enforce_dom0_cpus/01_enforce_dom0_cpus_basic_pos.py   
Tue Jun 13 09:00:32 2006 -0600
+++ b/tools/xm-test/tests/enforce_dom0_cpus/01_enforce_dom0_cpus_basic_pos.py   
Tue Jun 13 12:12:24 2006 -0600
@@ -28,6 +28,12 @@ check_status = 1
 check_status = 1
 max_tries = 10
 
+def reset_vcpu_count():
+    status, output = traceCommand("xm vcpu-set 0 %s"%(dom0_online_vcpus))
+    if status != 0:
+        print "WARNING!!! Unable to set vcpus back to %s, please set manually"\
+            %(dom0_online_vcpus)
+
 # 1) Make sure we have a multi cpu system and dom0 has at least 2 vcpus online.
 
 if smpConcurrencyLevel() <= 1:
@@ -57,6 +63,7 @@ if check_status and status != 0:
 # 4) restart xend with new config
 os.putenv("XEND_CONFIG", "/tmp/xend-config.sxp")
 status = restartXend()
+os.unsetenv("XEND_CONFIG")
 if check_status and status != 0:
     ns, no = restartXend()
     if ns != 0:
@@ -75,7 +82,7 @@ while timeout + starttime > time.time():
     cmd = "grep \"^processor\" /proc/cpuinfo | wc -l"
     status, output = traceCommand(cmd)
     if check_status and status != 0:
-        os.unsetenv("XEND_CONFIG")
+        reset_vcpu_count()
         restartXend()
         FAIL("\"%s\" returned invalid %i != 0" %(cmd,status))
 # Has it succeeded? If so, we can leave the loop
@@ -84,7 +91,7 @@ while timeout + starttime > time.time():
 # Sleep for 1 second before trying again
     time.sleep(1)
 if output != str(enforce_dom0_cpus):
-    os.unsetenv("XEND_CONFIG")
+    reset_vcpu_count()
     restartXend()
     FAIL("/proc/cpuinfo says xend didn't enforce dom0_cpus (%s != 
%s)"%(output, 
                                                              
enforce_dom0_cpus))
@@ -92,17 +99,13 @@ if output != str(enforce_dom0_cpus):
 # 6) count number of online cpus and see that it matches enforce value
 num_online = int(getDomInfo("Domain-0", "VCPUs"))
 if num_online != enforce_dom0_cpus:
-    os.unsetenv("XEND_CONFIG")
+    reset_vcpu_count()
     restartXend()
     FAIL("xm says xend didn't enforce dom0_cpus (%s != %s)" %(num_online, 
                                                              
enforce_dom0_cpus))
 
 # 7) restore dead processors 
-status, output = traceCommand("xm vcpu-set 0 %s"%(dom0_online_vcpus))
-if check_status and status != 0:
-    os.unsetenv("XEND_CONFIG")
-    restartXend()
-    FAIL("\"%s\" returned invalid %i != 0" %(cmd,status))
+reset_vcpu_count()
 
 # check restore worked
 # Since this also takes time, we will do it in a loop with a 20 second timeout.
@@ -114,12 +117,10 @@ while timeout + starttime > time.time():
         break
     time.sleep(1)
 if num_online != dom0_online_vcpus:
-    os.unsetenv("XEND_CONFIG")
     restartXend()
     FAIL("failed to restore dom0's VCPUs")
 
 
 # 8) Restart xend with default config
-os.unsetenv("XEND_CONFIG")
 restartXend()
 
diff -r b8f6089cbce3 -r e74c47d073ee xen/acm/acm_core.c
--- a/xen/acm/acm_core.c        Tue Jun 13 09:00:32 2006 -0600
+++ b/xen/acm/acm_core.c        Tue Jun 13 12:12:24 2006 -0600
@@ -316,7 +316,7 @@ acm_init_domain_ssid(domid_t id, ssidref
         return ACM_INIT_SSID_ERROR;
     }
 
-    ssid->datatype       = DOMAIN;
+    ssid->datatype       = ACM_DATATYPE_domain;
     ssid->subject        = subj;
     ssid->domainid      = subj->domain_id;
     ssid->primary_ssid   = NULL;
diff -r b8f6089cbce3 -r e74c47d073ee xen/acm/acm_policy.c
--- a/xen/acm/acm_policy.c      Tue Jun 13 09:00:32 2006 -0600
+++ b/xen/acm/acm_policy.c      Tue Jun 13 12:12:24 2006 -0600
@@ -32,7 +32,7 @@
 #include <acm/acm_endian.h>
 
 int
-acm_set_policy(void *buf, u32 buf_size, int isuserbuffer)
+acm_set_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size, int isuserbuffer)
 {
     u8 *policy_buffer = NULL;
     struct acm_policy_buffer *pol;
@@ -45,7 +45,7 @@ acm_set_policy(void *buf, u32 buf_size, 
         return -ENOMEM;
 
     if (isuserbuffer) {
-        if (copy_from_user(policy_buffer, buf, buf_size))
+        if (copy_from_guest(policy_buffer, buf, buf_size))
         {
             printk("%s: Error copying!\n",__func__);
             goto error_free;
@@ -116,7 +116,7 @@ acm_set_policy(void *buf, u32 buf_size, 
 }
 
 int
-acm_get_policy(void *buf, u32 buf_size)
+acm_get_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size)
 { 
     u8 *policy_buffer;
     int ret;
@@ -162,7 +162,7 @@ acm_get_policy(void *buf, u32 buf_size)
         goto error_free_unlock;
 
     bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
-    if (copy_to_user(buf, policy_buffer, ntohl(bin_pol->len)))
+    if (copy_to_guest(buf, policy_buffer, ntohl(bin_pol->len)))
         goto error_free_unlock;
 
     read_unlock(&acm_bin_pol_rwlock);
@@ -177,7 +177,7 @@ acm_get_policy(void *buf, u32 buf_size)
 }
 
 int
-acm_dump_statistics(void *buf, u16 buf_size)
+acm_dump_statistics(XEN_GUEST_HANDLE(void) buf, u16 buf_size)
 { 
     /* send stats to user space */
     u8 *stats_buffer;
@@ -208,7 +208,7 @@ acm_dump_statistics(void *buf, u16 buf_s
 
     memcpy(stats_buffer, &acm_stats, sizeof(struct acm_stats_buffer));
 
-    if (copy_to_user(buf, stats_buffer, sizeof(struct acm_stats_buffer) + len1 
+ len2))
+    if (copy_to_guest(buf, stats_buffer, sizeof(struct acm_stats_buffer) + 
len1 + len2))
         goto error_lock_free;
 
     read_unlock(&acm_bin_pol_rwlock);
@@ -223,7 +223,7 @@ acm_dump_statistics(void *buf, u16 buf_s
 
 
 int
-acm_get_ssid(ssidref_t ssidref, u8 *buf, u16 buf_size)
+acm_get_ssid(ssidref_t ssidref, XEN_GUEST_HANDLE(void) buf, u16 buf_size)
 {
     /* send stats to user space */
     u8 *ssid_buffer;
@@ -272,7 +272,7 @@ acm_get_ssid(ssidref_t ssidref, u8 *buf,
     acm_ssid->len += ret;
     acm_ssid->secondary_max_types = ret;
 
-    if (copy_to_user(buf, ssid_buffer, acm_ssid->len))
+    if (copy_to_guest(buf, ssid_buffer, acm_ssid->len))
         goto error_free_unlock;
 
     read_unlock(&acm_bin_pol_rwlock);
@@ -287,14 +287,13 @@ acm_get_ssid(ssidref_t ssidref, u8 *buf,
 }
 
 int
-acm_get_decision(ssidref_t ssidref1, ssidref_t ssidref2,
-                 enum acm_hook_type hook)
+acm_get_decision(ssidref_t ssidref1, ssidref_t ssidref2, u32 hook)
 {
     int ret = ACM_ACCESS_DENIED;
     switch (hook) {
 
-    case SHARING:
-        /* SHARING Hook restricts access in STE policy only */
+    case ACMHOOK_sharing:
+        /* Sharing hook restricts access in STE policy only */
         ret = acm_sharing(ssidref1, ssidref2);
         break;
 
diff -r b8f6089cbce3 -r e74c47d073ee xen/acm/acm_simple_type_enforcement_hooks.c
--- a/xen/acm/acm_simple_type_enforcement_hooks.c       Tue Jun 13 09:00:32 
2006 -0600
+++ b/xen/acm/acm_simple_type_enforcement_hooks.c       Tue Jun 13 12:12:24 
2006 -0600
@@ -117,7 +117,7 @@ ste_init_domain_ssid(void **ste_ssid, ss
     }
     /* clean ste cache */
     for (i=0; i<ACM_TE_CACHE_SIZE; i++)
-        ste_ssidp->ste_cache[i].valid = FREE;
+        ste_ssidp->ste_cache[i].valid = ACM_STE_free;
 
     (*ste_ssid) = ste_ssidp;
     printkd("%s: determined ste_ssidref to %x.\n", 
@@ -329,7 +329,7 @@ ste_set_policy(u8 *buf, u32 buf_size)
         ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
                              (struct acm_ssid_domain *)(*pd)->ssid);
         for (i=0; i<ACM_TE_CACHE_SIZE; i++)
-            ste_ssid->ste_cache[i].valid = FREE;
+            ste_ssid->ste_cache[i].valid = ACM_STE_free;
     }
     read_unlock(&domlist_lock);
     return ACM_OK;
@@ -397,7 +397,7 @@ check_cache(struct domain *dom, domid_t 
                          (struct acm_ssid_domain *)(dom->ssid));
 
     for(i=0; i< ACM_TE_CACHE_SIZE; i++) {
-        if ((ste_ssid->ste_cache[i].valid == VALID) &&
+        if ((ste_ssid->ste_cache[i].valid == ACM_STE_valid) &&
             (ste_ssid->ste_cache[i].id == rdom)) {
             printkd("cache hit (entry %x, id= %x!\n", i, 
ste_ssid->ste_cache[i].id);
             return 1;
@@ -418,10 +418,10 @@ cache_result(struct domain *subj, struct
     ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
                          (struct acm_ssid_domain *)(subj)->ssid);
     for(i=0; i< ACM_TE_CACHE_SIZE; i++)
-        if (ste_ssid->ste_cache[i].valid == FREE)
+        if (ste_ssid->ste_cache[i].valid == ACM_STE_free)
             break;
     if (i< ACM_TE_CACHE_SIZE) {
-        ste_ssid->ste_cache[i].valid = VALID;
+        ste_ssid->ste_cache[i].valid = ACM_STE_valid;
         ste_ssid->ste_cache[i].id = obj->domain_id;
     } else
         printk ("Cache of dom %x is full!\n", subj->domain_id);
@@ -451,9 +451,9 @@ clean_id_from_cache(domid_t id)
             goto out;
         }
         for (i=0; i<ACM_TE_CACHE_SIZE; i++)
-            if ((ste_ssid->ste_cache[i].valid == VALID) &&
+            if ((ste_ssid->ste_cache[i].valid == ACM_STE_valid) &&
                 (ste_ssid->ste_cache[i].id == id))
-                ste_ssid->ste_cache[i].valid = FREE;
+                ste_ssid->ste_cache[i].valid = ACM_STE_free;
     }
  out:
     read_unlock(&domlist_lock);
diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/ia64/linux-xen/smpboot.c
--- a/xen/arch/ia64/linux-xen/smpboot.c Tue Jun 13 09:00:32 2006 -0600
+++ b/xen/arch/ia64/linux-xen/smpboot.c Tue Jun 13 12:12:24 2006 -0600
@@ -62,6 +62,7 @@
 #include <asm/unistd.h>
 
 #ifdef XEN
+#include <xen/domain.h>
 #include <asm/hw_irq.h>
 int ht_per_core = 1;
 #ifndef CONFIG_SMP
@@ -487,7 +488,7 @@ do_rest:
 #else
        struct vcpu *v;
 
-       v = idle_vcpu[cpu] = alloc_vcpu(idle_vcpu[0]->domain, cpu, cpu);
+       v = alloc_idle_vcpu(cpu);
        BUG_ON(v == NULL);
 
        //printf ("do_boot_cpu: cpu=%d, domain=%p, vcpu=%p\n", cpu, idle, v);
diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/ia64/vmx/vmx_init.c
--- a/xen/arch/ia64/vmx/vmx_init.c      Tue Jun 13 09:00:32 2006 -0600
+++ b/xen/arch/ia64/vmx/vmx_init.c      Tue Jun 13 12:12:24 2006 -0600
@@ -288,9 +288,6 @@ vmx_final_setup_guest(struct vcpu *v)
        /* v->arch.schedule_tail = arch_vmx_do_launch; */
        vmx_create_vp(v);
 
-       /* Set this ed to be vmx */
-       set_bit(ARCH_VMX_VMCS_LOADED, &v->arch.arch_vmx.flags);
-
        /* Physical mode emulation initialization, including
        * emulation ID allcation and related memory request
        */
diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c        Tue Jun 13 09:00:32 2006 -0600
+++ b/xen/arch/ia64/xen/domain.c        Tue Jun 13 12:12:24 2006 -0600
@@ -46,6 +46,7 @@
 
 #include <asm/vcpu.h>   /* for function declarations */
 #include <public/arch-ia64.h>
+#include <xen/domain.h>
 #include <asm/vmx.h>
 #include <asm/vmx_vcpu.h>
 #include <asm/vmx_vpd.h>
diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/ia64/xen/xensetup.c
--- a/xen/arch/ia64/xen/xensetup.c      Tue Jun 13 09:00:32 2006 -0600
+++ b/xen/arch/ia64/xen/xensetup.c      Tue Jun 13 12:12:24 2006 -0600
@@ -35,8 +35,6 @@ char saved_command_line[COMMAND_LINE_SIZ
 char saved_command_line[COMMAND_LINE_SIZE];
 char dom0_command_line[COMMAND_LINE_SIZE];
 
-struct vcpu *idle_vcpu[NR_CPUS];
-
 cpumask_t cpu_present_map;
 
 extern unsigned long domain0_ready;
diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/x86/audit.c
--- a/xen/arch/x86/audit.c      Tue Jun 13 09:00:32 2006 -0600
+++ b/xen/arch/x86/audit.c      Tue Jun 13 12:12:24 2006 -0600
@@ -432,10 +432,10 @@ int audit_adjust_pgtables(struct domain 
 
         for_each_vcpu(d, v)
         {
-            if ( pagetable_get_paddr(v->arch.guest_table) )
+            if ( !pagetable_is_null(v->arch.guest_table) )
                 adjust(mfn_to_page(pagetable_get_pfn(v->arch.guest_table)),
                        !shadow_mode_refcounts(d));
-            if ( pagetable_get_paddr(v->arch.shadow_table) )
+            if ( !pagetable_is_null(v->arch.shadow_table) )
                 adjust(mfn_to_page(pagetable_get_pfn(v->arch.shadow_table)),
                        0);
             if ( v->arch.monitor_shadow_ref )
diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/x86/cpu/mtrr/main.c
--- a/xen/arch/x86/cpu/mtrr/main.c      Tue Jun 13 09:00:32 2006 -0600
+++ b/xen/arch/x86/cpu/mtrr/main.c      Tue Jun 13 12:12:24 2006 -0600
@@ -43,7 +43,7 @@
 #include "mtrr.h"
 
 /* No blocking mutexes in Xen. Spin instead. */
-#define DECLARE_MUTEX(_m) spinlock_t _m = SPIN_LOCK_UNLOCKED
+#define DECLARE_MUTEX(_m) DEFINE_SPINLOCK(_m)
 #define down(_m) spin_lock(_m)
 #define up(_m) spin_unlock(_m)
 #define lock_cpu_hotplug() ((void)0)
diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/x86/dom0_ops.c
--- a/xen/arch/x86/dom0_ops.c   Tue Jun 13 09:00:32 2006 -0600
+++ b/xen/arch/x86/dom0_ops.c   Tue Jun 13 12:12:24 2006 -0600
@@ -467,7 +467,7 @@ void arch_getdomaininfo_ctxt(
     if ( hvm_guest(v) )
         c->flags |= VGCF_HVM_GUEST;
 
-    c->ctrlreg[3] = pagetable_get_paddr(v->arch.guest_table);
+    c->ctrlreg[3] = xen_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table));
 
     c->vm_assist = v->domain->vm_assist;
 }
diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Tue Jun 13 09:00:32 2006 -0600
+++ b/xen/arch/x86/domain.c     Tue Jun 13 12:12:24 2006 -0600
@@ -259,7 +259,7 @@ int arch_set_info_guest(
     struct vcpu *v, struct vcpu_guest_context *c)
 {
     struct domain *d = v->domain;
-    unsigned long phys_basetab = INVALID_MFN;
+    unsigned long cr3_pfn = INVALID_MFN;
     int i, rc;
 
     if ( !(c->flags & VGCF_HVM_GUEST) )
@@ -322,12 +322,8 @@ int arch_set_info_guest(
 
     if ( !(c->flags & VGCF_HVM_GUEST) )
     {
-        phys_basetab = c->ctrlreg[3];
-        phys_basetab =
-            (gmfn_to_mfn(d, phys_basetab >> PAGE_SHIFT) << PAGE_SHIFT) |
-            (phys_basetab & ~PAGE_MASK);
-
-        v->arch.guest_table = mk_pagetable(phys_basetab);
+        cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c->ctrlreg[3]));
+        v->arch.guest_table = pagetable_from_pfn(cr3_pfn);
     }
 
     if ( (rc = (int)set_gdt(v, c->gdt_frames, c->gdt_ents)) != 0 )
@@ -335,14 +331,14 @@ int arch_set_info_guest(
 
     if ( c->flags & VGCF_HVM_GUEST )
     {
-        v->arch.guest_table = mk_pagetable(0);
+        v->arch.guest_table = pagetable_null();
 
         if ( !hvm_initialize_guest_resources(v) )
             return -EINVAL;
     }
     else if ( shadow_mode_refcounts(d) )
     {
-        if ( !get_page(mfn_to_page(phys_basetab>>PAGE_SHIFT), d) )
+        if ( !get_page(mfn_to_page(cr3_pfn), d) )
         {
             destroy_gdt(v);
             return -EINVAL;
@@ -350,7 +346,7 @@ int arch_set_info_guest(
     }
     else
     {
-        if ( !get_page_and_type(mfn_to_page(phys_basetab>>PAGE_SHIFT), d,
+        if ( !get_page_and_type(mfn_to_page(cr3_pfn), d,
                                 PGT_base_page_table) )
         {
             destroy_gdt(v);
@@ -381,10 +377,6 @@ arch_do_vcpu_op(
     {
         struct vcpu_register_runstate_memory_area area;
 
-        rc = -EINVAL;
-        if ( v != current )
-            break;
-
         rc = -EFAULT;
         if ( copy_from_guest(&area, arg, 1) )
             break;
@@ -394,7 +386,10 @@ arch_do_vcpu_op(
 
         rc = 0;
         v->runstate_guest = area.addr.v;
-        __copy_to_user(v->runstate_guest, &v->runstate, sizeof(v->runstate));
+
+        if ( v == current )
+            __copy_to_user(v->runstate_guest, &v->runstate,
+                           sizeof(v->runstate));
 
         break;
     }
@@ -528,20 +523,29 @@ static void load_segments(struct vcpu *n
     if ( unlikely(!all_segs_okay) )
     {
         struct cpu_user_regs *regs = guest_cpu_user_regs();
-        unsigned long   *rsp =
+        unsigned long *rsp =
             (n->arch.flags & TF_kernel_mode) ?
             (unsigned long *)regs->rsp :
             (unsigned long *)nctxt->kernel_sp;
+        unsigned long cs_and_mask, rflags;
 
         if ( !(n->arch.flags & TF_kernel_mode) )
             toggle_guest_mode(n);
         else
             regs->cs &= ~3;
 
+        /* CS longword also contains full evtchn_upcall_mask. */
+        cs_and_mask = (unsigned long)regs->cs |
+            ((unsigned long)n->vcpu_info->evtchn_upcall_mask << 32);
+
+        /* Fold upcall mask into RFLAGS.IF. */
+        rflags  = regs->rflags & ~X86_EFLAGS_IF;
+        rflags |= !n->vcpu_info->evtchn_upcall_mask << 9;
+
         if ( put_user(regs->ss,            rsp- 1) |
              put_user(regs->rsp,           rsp- 2) |
-             put_user(regs->rflags,        rsp- 3) |
-             put_user(regs->cs,            rsp- 4) |
+             put_user(rflags,              rsp- 3) |
+             put_user(cs_and_mask,         rsp- 4) |
              put_user(regs->rip,           rsp- 5) |
              put_user(nctxt->user_regs.gs, rsp- 6) |
              put_user(nctxt->user_regs.fs, rsp- 7) |
@@ -553,6 +557,10 @@ static void load_segments(struct vcpu *n
             DPRINTK("Error while creating failsafe callback frame.\n");
             domain_crash(n->domain);
         }
+
+        if ( test_bit(_VGCF_failsafe_disables_events,
+                      &n->arch.guest_context.flags) )
+            n->vcpu_info->evtchn_upcall_mask = 1;
 
         regs->entry_vector  = TRAP_syscall;
         regs->rflags       &= 0xFFFCBEFFUL;
@@ -935,7 +943,7 @@ void domain_relinquish_resources(struct 
                 put_page_type(mfn_to_page(pfn));
             put_page(mfn_to_page(pfn));
 
-            v->arch.guest_table = mk_pagetable(0);
+            v->arch.guest_table = pagetable_null();
         }
 
         if ( (pfn = pagetable_get_pfn(v->arch.guest_table_user)) != 0 )
@@ -944,7 +952,7 @@ void domain_relinquish_resources(struct 
                 put_page_type(mfn_to_page(pfn));
             put_page(mfn_to_page(pfn));
 
-            v->arch.guest_table_user = mk_pagetable(0);
+            v->arch.guest_table_user = pagetable_null();
         }
     }
 
diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c       Tue Jun 13 09:00:32 2006 -0600
+++ b/xen/arch/x86/domain_build.c       Tue Jun 13 12:12:24 2006 -0600
@@ -301,6 +301,9 @@ int construct_dom0(struct domain *d,
                xen_pae ? "yes" : "no", dom0_pae ? "yes" : "no");
         return -EINVAL;
     }
+
+    if ( xen_pae && !!strstr(dsi.xen_section_string, "PAE=yes[extended-cr3]") )
+        set_bit(VMASST_TYPE_pae_extended_cr3, &d->vm_assist);
 
     if ( (p = strstr(dsi.xen_section_string, "FEATURES=")) != NULL )
     {
@@ -443,13 +446,13 @@ int construct_dom0(struct domain *d,
         l2tab[(LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT)+i] =
             l2e_from_paddr((u32)l2tab + i*PAGE_SIZE, __PAGE_HYPERVISOR);
     }
-    v->arch.guest_table = mk_pagetable((unsigned long)l3start);
+    v->arch.guest_table = pagetable_from_paddr((unsigned long)l3start);
 #else
     l2start = l2tab = (l2_pgentry_t *)mpt_alloc; mpt_alloc += PAGE_SIZE;
     memcpy(l2tab, idle_pg_table, PAGE_SIZE);
     l2tab[LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT] =
         l2e_from_paddr((unsigned long)l2start, __PAGE_HYPERVISOR);
-    v->arch.guest_table = mk_pagetable((unsigned long)l2start);
+    v->arch.guest_table = pagetable_from_paddr((unsigned long)l2start);
 #endif
 
     for ( i = 0; i < PDPT_L2_ENTRIES; i++ )
@@ -577,7 +580,7 @@ int construct_dom0(struct domain *d,
         l4e_from_paddr(__pa(l4start), __PAGE_HYPERVISOR);
     l4tab[l4_table_offset(PERDOMAIN_VIRT_START)] =
         l4e_from_paddr(__pa(d->arch.mm_perdomain_l3), __PAGE_HYPERVISOR);
-    v->arch.guest_table = mk_pagetable(__pa(l4start));
+    v->arch.guest_table = pagetable_from_paddr(__pa(l4start));
 
     l4tab += l4_table_offset(dsi.v_start);
     mfn = alloc_spfn;
diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/x86/hvm/intercept.c
--- a/xen/arch/x86/hvm/intercept.c      Tue Jun 13 09:00:32 2006 -0600
+++ b/xen/arch/x86/hvm/intercept.c      Tue Jun 13 12:12:24 2006 -0600
@@ -216,13 +216,14 @@ void hlt_timer_fn(void *data)
 
 static __inline__ void missed_ticks(struct periodic_time *pt)
 {
-    int missed_ticks;
-
-    missed_ticks = (NOW() - pt->scheduled)/(s_time_t) pt->period;
-    if ( missed_ticks++ >= 0 ) {
+    s_time_t missed_ticks;
+
+    missed_ticks = NOW() - pt->scheduled;
+    if ( missed_ticks > 0 ) {
+       missed_ticks = missed_ticks / (s_time_t) pt->period + 1;
         if ( missed_ticks > 1000 ) {
             /* TODO: Adjust guest time togther */
-            pt->pending_intr_nr ++;
+            pt->pending_intr_nr++;
         }
         else {
             pt->pending_intr_nr += missed_ticks;
@@ -236,6 +237,9 @@ void pt_timer_fn(void *data)
 {
     struct vcpu *v = data;
     struct periodic_time *pt = 
&(v->domain->arch.hvm_domain.pl_time.periodic_tm);
+
+    pt->pending_intr_nr++;
+    pt->scheduled += pt->period;
 
     /* pick up missed timer tick */
     missed_ticks(pt);
diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/x86/hvm/io.c
--- a/xen/arch/x86/hvm/io.c     Tue Jun 13 09:00:32 2006 -0600
+++ b/xen/arch/x86/hvm/io.c     Tue Jun 13 12:12:24 2006 -0600
@@ -507,6 +507,13 @@ static void hvm_mmio_assist(struct vcpu 
             regs->ecx -= p->count;
         break;
 
+    case INSTR_LODS:
+        sign = p->df ? -1 : 1;
+        regs->esi += sign * p->count * p->size;
+        if (mmio_opp->flags & REPZ)
+            regs->ecx -= p->count;
+        break;
+
     case INSTR_AND:
         if (src & REGISTER) {
             index = operand_index(src);
diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/x86/hvm/platform.c
--- a/xen/arch/x86/hvm/platform.c       Tue Jun 13 09:00:32 2006 -0600
+++ b/xen/arch/x86/hvm/platform.c       Tue Jun 13 12:12:24 2006 -0600
@@ -364,6 +364,12 @@ static int hvm_decode(int realmode, unsi
     }
 
     switch (*opcode) {
+    case 0x0A: /* or r8, m8 */
+        instr->instr = INSTR_OR;
+        instr->op_size = BYTE;
+        GET_OP_SIZE_FOR_BYTE(size_reg);
+        return mem_reg(size_reg, opcode, instr, rex);
+
     case 0x0B: /* or m32/16, r32/16 */
         instr->instr = INSTR_OR;
         GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
@@ -380,6 +386,12 @@ static int hvm_decode(int realmode, unsi
         GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
         return reg_mem(instr->op_size, opcode, instr, rex);
 
+    case 0x22: /* and m8, r8 */
+        instr->instr = INSTR_AND;
+        instr->op_size = BYTE;
+        GET_OP_SIZE_FOR_BYTE(size_reg);
+        return mem_reg(size_reg, opcode, instr, rex);
+
     case 0x23: /* and m32/16, r32/16 */
         instr->instr = INSTR_AND;
         GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
@@ -396,6 +408,12 @@ static int hvm_decode(int realmode, unsi
         GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
         return reg_mem(instr->op_size, opcode, instr, rex);
 
+    case 0x32: /* xor m8, r8*/
+        instr->instr = INSTR_XOR;
+        instr->op_size = BYTE;
+        GET_OP_SIZE_FOR_BYTE(size_reg);
+        return mem_reg(size_reg, opcode, instr, rex);
+
     case 0x39: /* cmp r32/16, m32/16 */
         instr->instr = INSTR_CMP;
         GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
@@ -408,19 +426,30 @@ static int hvm_decode(int realmode, unsi
 
     case 0x80:
     case 0x81:
+    case 0x83:
         {
             unsigned char ins_subtype = (opcode[1] >> 3) & 7;
 
             if (opcode[0] == 0x80) {
                 GET_OP_SIZE_FOR_BYTE(size_reg);
                 instr->op_size = BYTE;
-            } else {
+            } else if (opcode[0] == 0x81) {
                 GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
                 size_reg = instr->op_size;
+            } else if (opcode[0] == 0x83) {
+                GET_OP_SIZE_FOR_NONEBYTE(size_reg);
+                instr->op_size = size_reg;
             }
+           
+            /* opcode 0x83 always has a single byte operand */
+            if (opcode[0] == 0x83)
+                instr->immediate = 
+                    (signed char)get_immediate(realmode, opcode+1, BYTE);
+            else
+                instr->immediate = 
+                    get_immediate(realmode, opcode+1, instr->op_size);
 
             instr->operand[0] = mk_operand(size_reg, 0, 0, IMMEDIATE);
-            instr->immediate = get_immediate(realmode, opcode+1, 
instr->op_size);
             instr->operand[1] = mk_operand(size_reg, 0, 0, MEMORY);
 
             switch (ins_subtype) {
@@ -513,6 +542,16 @@ static int hvm_decode(int realmode, unsi
 
     case 0xAB: /* stosw/stosl */
         instr->instr = INSTR_STOS;
+        GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
+        return DECODE_success;
+
+    case 0xAC: /* lodsb */
+        instr->instr = INSTR_LODS;
+        instr->op_size = BYTE;
+        return DECODE_success;
+
+    case 0xAD: /* lodsw/lodsl */
+        instr->instr = INSTR_LODS;
         GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
         return DECODE_success;
 
@@ -906,6 +945,17 @@ void handle_mmio(unsigned long va, unsig
                       GET_REPEAT_COUNT(), mmio_inst.op_size, regs->eax, 
IOREQ_WRITE, 0);
         break;
 
+    case INSTR_LODS:
+        /*
+         * Since the source is always in (contiguous) mmio space we don't
+         * need to break it up into pages.
+         */
+        mmio_opp->flags = mmio_inst.flags;
+        mmio_opp->instr = mmio_inst.instr;
+        send_mmio_req(IOREQ_TYPE_COPY, gpa,
+                      GET_REPEAT_COUNT(), mmio_inst.op_size, 0, IOREQ_READ, 0);
+        break;
+
     case INSTR_OR:
         mmio_operands(IOREQ_TYPE_OR, gpa, &mmio_inst, mmio_opp, regs);
         break;
@@ -954,26 +1004,26 @@ void handle_mmio(unsigned long va, unsig
         mmio_opp->instr = mmio_inst.instr;
         mmio_opp->operand[0] = mmio_inst.operand[0]; /* source */
         mmio_opp->operand[1] = mmio_inst.operand[1]; /* destination */
-       if (mmio_inst.operand[0] & REGISTER) {
-               long value;
-               unsigned long operand = mmio_inst.operand[0];
-               value = get_reg_value(operand_size(operand), 
-                                     operand_index(operand), 0,
-                                     mmio_opp->inst_decoder_regs);
-               /* send the request and wait for the value */
-               send_mmio_req(IOREQ_TYPE_XCHG, gpa, 1,
-                      mmio_inst.op_size, value, IOREQ_WRITE, 0);
-       } else {
-               /* the destination is a register */
-               long value;
-               unsigned long operand = mmio_inst.operand[1];
-               value = get_reg_value(operand_size(operand), 
-                                     operand_index(operand), 0,
-                                     mmio_opp->inst_decoder_regs);
-               /* send the request and wait for the value */
-               send_mmio_req(IOREQ_TYPE_XCHG, gpa, 1,
-                      mmio_inst.op_size, value, IOREQ_WRITE, 0);
-       }
+        if ( mmio_inst.operand[0] & REGISTER ) {
+            long value;
+            unsigned long operand = mmio_inst.operand[0];
+            value = get_reg_value(operand_size(operand),
+                                  operand_index(operand), 0,
+                                  mmio_opp->inst_decoder_regs);
+            /* send the request and wait for the value */
+            send_mmio_req(IOREQ_TYPE_XCHG, gpa, 1,
+                          mmio_inst.op_size, value, IOREQ_WRITE, 0);
+        } else {
+            /* the destination is a register */
+            long value;
+            unsigned long operand = mmio_inst.operand[1];
+            value = get_reg_value(operand_size(operand),
+                                  operand_index(operand), 0,
+                                  mmio_opp->inst_decoder_regs);
+            /* send the request and wait for the value */
+            send_mmio_req(IOREQ_TYPE_XCHG, gpa, 1,
+                          mmio_inst.op_size, value, IOREQ_WRITE, 0);
+        }
         break;
 
     default:
diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Tue Jun 13 09:00:32 2006 -0600
+++ b/xen/arch/x86/hvm/svm/svm.c        Tue Jun 13 12:12:24 2006 -0600
@@ -84,28 +84,26 @@ struct svm_percore_globals svm_globals[N
 /*
  * Initializes the POOL of ASID used by the guests per core.
  */
-void asidpool_init( int core )
+void asidpool_init(int core)
 {
     int i;
-    svm_globals[core].ASIDpool.asid_lock = SPIN_LOCK_UNLOCKED;
-    spin_lock(&svm_globals[core].ASIDpool.asid_lock);
+
+    spin_lock_init(&svm_globals[core].ASIDpool.asid_lock);
+
     /* Host ASID is always in use */
     svm_globals[core].ASIDpool.asid[INITIAL_ASID] = ASID_INUSE;
-    for( i=1; i<ASID_MAX; i++ )
-    {
+    for ( i = 1; i < ASID_MAX; i++ )
        svm_globals[core].ASIDpool.asid[i] = ASID_AVAILABLE;
-    }
-    spin_unlock(&svm_globals[core].ASIDpool.asid_lock);
 }
 
 
 /* internal function to get the next available ASID */
-static int asidpool_fetch_next( struct vmcb_struct *vmcb, int core )
+static int asidpool_fetch_next(struct vmcb_struct *vmcb, int core)
 {
     int i;   
-    for( i = 1; i < ASID_MAX; i++ )
-    {
-        if( svm_globals[core].ASIDpool.asid[i] == ASID_AVAILABLE )
+    for ( i = 1; i < ASID_MAX; i++ )
+    {
+        if ( svm_globals[core].ASIDpool.asid[i] == ASID_AVAILABLE )
         {
             vmcb->guest_asid = i;
             svm_globals[core].ASIDpool.asid[i] = ASID_INUSE;
@@ -746,34 +744,34 @@ static void svm_ctxt_switch_to(struct vc
 
 void svm_final_setup_guest(struct vcpu *v)
 {
+    struct domain *d = v->domain;
+    struct vcpu *vc;
+
     v->arch.schedule_tail    = arch_svm_do_launch;
     v->arch.ctxt_switch_from = svm_ctxt_switch_from;
     v->arch.ctxt_switch_to   = svm_ctxt_switch_to;
 
-    if (v == v->domain->vcpu[0]) 
-    {
-       struct domain *d = v->domain;
-       struct vcpu *vc;
-
-       /* Initialize monitor page table */
-       for_each_vcpu(d, vc)
-           vc->arch.monitor_table = mk_pagetable(0);
-
-        /* 
-         * Required to do this once per domain
-         * TODO: add a seperate function to do these.
-         */
-        memset(&d->shared_info->evtchn_mask[0], 0xff, 
-               sizeof(d->shared_info->evtchn_mask));       
-
-        /* 
-         * Put the domain in shadow mode even though we're going to be using
-         * the shared 1:1 page table initially. It shouldn't hurt 
-         */
-        shadow_mode_enable(d, 
-                SHM_enable|SHM_refcounts|
-               SHM_translate|SHM_external|SHM_wr_pt_pte);
-    }
+    if ( v != d->vcpu[0] )
+        return;
+
+    /* Initialize monitor page table */
+    for_each_vcpu( d, vc )
+        vc->arch.monitor_table = pagetable_null();
+
+    /* 
+     * Required to do this once per domain
+     * TODO: add a seperate function to do these.
+     */
+    memset(&d->shared_info->evtchn_mask[0], 0xff, 
+           sizeof(d->shared_info->evtchn_mask));       
+
+    /* 
+     * Put the domain in shadow mode even though we're going to be using
+     * the shared 1:1 page table initially. It shouldn't hurt 
+     */
+    shadow_mode_enable(d,
+                       SHM_enable|SHM_refcounts|
+                       SHM_translate|SHM_external|SHM_wr_pt_pte);
 }
 
 
@@ -870,7 +868,7 @@ static int svm_do_page_fault(unsigned lo
     /* Use 1:1 page table to identify MMIO address space */
     if (mmio_space(gpa))
     {
-       /* No support for APIC */
+        /* No support for APIC */
         if (!hvm_apic_support(v->domain) && gpa >= 0xFEC00000)
         { 
             int inst_len;
@@ -1570,7 +1568,7 @@ static int svm_set_cr0(unsigned long val
         }
 
         /* Now arch.guest_table points to machine physical. */
-        v->arch.guest_table = mk_pagetable((u64)mfn << PAGE_SHIFT);
+        v->arch.guest_table = pagetable_from_pfn(mfn);
         update_pagetables(v);
 
         HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx", 
@@ -1590,7 +1588,7 @@ static int svm_set_cr0(unsigned long val
         if ( v->arch.hvm_svm.cpu_cr3 ) {
             put_page(mfn_to_page(get_mfn_from_gpfn(
                       v->arch.hvm_svm.cpu_cr3 >> PAGE_SHIFT)));
-            v->arch.guest_table = mk_pagetable(0);
+            v->arch.guest_table = pagetable_null();
         }
 
     /*
@@ -1599,7 +1597,7 @@ static int svm_set_cr0(unsigned long val
      * created.
      */
     if ((value & X86_CR0_PE) == 0) {
-       if (value & X86_CR0_PG) {
+        if (value & X86_CR0_PG) {
             svm_inject_exception(v, TRAP_gp_fault, 1, 0);
             return 0;
         }
@@ -1740,7 +1738,7 @@ static int mov_to_cr(int gpreg, int cr, 
             }
 
             old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
-            v->arch.guest_table = mk_pagetable((u64)mfn << PAGE_SHIFT);
+            v->arch.guest_table = pagetable_from_pfn(mfn);
 
             if (old_base_mfn)
                 put_page(mfn_to_page(old_base_mfn));
@@ -1797,7 +1795,7 @@ static int mov_to_cr(int gpreg, int cr, 
                  * Now arch.guest_table points to machine physical.
                  */
 
-                v->arch.guest_table = mk_pagetable((u64)mfn << PAGE_SHIFT);
+                v->arch.guest_table = pagetable_from_pfn(mfn);
                 update_pagetables(v);
 
                 HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Tue Jun 13 09:00:32 2006 -0600
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Tue Jun 13 12:12:24 2006 -0600
@@ -42,7 +42,7 @@
 
 int vmcs_size;
 
-struct vmcs_struct *alloc_vmcs(void)
+struct vmcs_struct *vmx_alloc_vmcs(void)
 {
     struct vmcs_struct *vmcs;
     u32 vmx_msr_low, vmx_msr_high;
@@ -64,47 +64,63 @@ static void free_vmcs(struct vmcs_struct
     free_xenheap_pages(vmcs, order);
 }
 
-static int load_vmcs(struct arch_vmx_struct *arch_vmx, u64 phys_ptr)
-{
-    int error;
-
-    if ((error = __vmptrld(phys_ptr))) {
-        clear_bit(ARCH_VMX_VMCS_LOADED, &arch_vmx->flags);
-        return error;
-    }
-    set_bit(ARCH_VMX_VMCS_LOADED, &arch_vmx->flags);
-    return 0;
-}
-
-static void vmx_smp_clear_vmcs(void *info)
-{
-    struct vcpu *v = (struct vcpu *)info;
-
-    ASSERT(hvm_guest(v));
-
-    if (v->arch.hvm_vmx.launch_cpu == smp_processor_id())
-        __vmpclear(virt_to_maddr(v->arch.hvm_vmx.vmcs));
-}
-
-void vmx_request_clear_vmcs(struct vcpu *v)
-{
-    ASSERT(hvm_guest(v));
-
-    if (v->arch.hvm_vmx.launch_cpu == smp_processor_id())
-        __vmpclear(virt_to_maddr(v->arch.hvm_vmx.vmcs));
+static void __vmx_clear_vmcs(void *info)
+{
+    struct vcpu *v = info;
+    __vmpclear(virt_to_maddr(v->arch.hvm_vmx.vmcs));
+    v->arch.hvm_vmx.active_cpu = -1;
+    v->arch.hvm_vmx.launched   = 0;
+}
+
+static void vmx_clear_vmcs(struct vcpu *v)
+{
+    unsigned int cpu = v->arch.hvm_vmx.active_cpu;
+
+    if ( (cpu == -1) || (cpu == smp_processor_id()) )
+        __vmx_clear_vmcs(v);
     else
-        smp_call_function(vmx_smp_clear_vmcs, v, 1, 1);
-}
-
-#if 0
-static int store_vmcs(struct arch_vmx_struct *arch_vmx, u64 phys_ptr)
-{
-    /* take the current VMCS */
-    __vmptrst(phys_ptr);
-    clear_bit(ARCH_VMX_VMCS_LOADED, &arch_vmx->flags);
-    return 0;
-}
-#endif
+        on_selected_cpus(cpumask_of_cpu(cpu), __vmx_clear_vmcs, v, 1, 1);
+}
+
+static void vmx_load_vmcs(struct vcpu *v)
+{
+    __vmptrld(virt_to_maddr(v->arch.hvm_vmx.vmcs));
+    v->arch.hvm_vmx.active_cpu = smp_processor_id();
+}
+
+void vmx_vmcs_enter(struct vcpu *v)
+{
+    /*
+     * NB. We must *always* run an HVM VCPU on its own VMCS, except for
+     * vmx_vmcs_enter/exit critical regions. This leads to some XXX TODOs XXX:
+     *  1. Move construct_vmcs() much earlier, to domain creation or
+     *     context initialisation.
+     *  2. VMPTRLD as soon as we context-switch to a HVM VCPU.
+     *  3. VMCS destruction needs to happen later (from domain_destroy()).
+     */
+    if ( v == current )
+        return;
+
+    vcpu_pause(v);
+    spin_lock(&v->arch.hvm_vmx.vmcs_lock);
+
+    vmx_clear_vmcs(v);
+    vmx_load_vmcs(v);
+}
+
+void vmx_vmcs_exit(struct vcpu *v)
+{
+    if ( v == current )
+        return;
+
+    /* Don't confuse arch_vmx_do_resume (for @v or @current!) */
+    vmx_clear_vmcs(v);
+    if ( hvm_guest(current) )
+        vmx_load_vmcs(current);
+
+    spin_unlock(&v->arch.hvm_vmx.vmcs_lock);
+    vcpu_unpause(v);
+}
 
 static inline int construct_vmcs_controls(struct arch_vmx_struct *arch_vmx)
 {
@@ -247,7 +263,6 @@ static void vmx_do_launch(struct vcpu *v
     __vmwrite(HOST_CR3, pagetable_get_paddr(v->arch.monitor_table));
 
     v->arch.schedule_tail = arch_vmx_do_resume;
-    v->arch.hvm_vmx.launch_cpu = smp_processor_id();
 
     /* init guest tsc to start from 0 */
     set_guest_time(v, 0);
@@ -410,53 +425,49 @@ static inline int construct_vmcs_host(vo
 /*
  * Need to extend to support full virtualization.
  */
-static int construct_vmcs(struct arch_vmx_struct *arch_vmx,
+static int construct_vmcs(struct vcpu *v,
                           cpu_user_regs_t *regs)
 {
+    struct arch_vmx_struct *arch_vmx = &v->arch.hvm_vmx;
     int error;
     long rc;
-    u64 vmcs_phys_ptr;
 
     memset(arch_vmx, 0, sizeof(struct arch_vmx_struct));
+
+    spin_lock_init(&arch_vmx->vmcs_lock);
+    arch_vmx->active_cpu = -1;
 
     /*
      * Create a new VMCS
      */
-    if (!(arch_vmx->vmcs = alloc_vmcs())) {
+    if (!(arch_vmx->vmcs = vmx_alloc_vmcs())) {
         printk("Failed to create a new VMCS\n");
-        rc = -ENOMEM;
-        goto err_out;
-    }
-    vmcs_phys_ptr = (u64) virt_to_maddr(arch_vmx->vmcs);
-
-    if ((error = __vmpclear(vmcs_phys_ptr))) {
-        printk("construct_vmcs: VMCLEAR failed\n");
-        rc = -EINVAL;
-        goto err_out;
-    }
-    if ((error = load_vmcs(arch_vmx, vmcs_phys_ptr))) {
-        printk("construct_vmcs: load_vmcs failed: VMCS = %lx\n",
-               (unsigned long) vmcs_phys_ptr);
-        rc = -EINVAL;
-        goto err_out;
-    }
+        return -ENOMEM;
+    }
+
+    vmx_clear_vmcs(v);
+    vmx_load_vmcs(v);
+
     if ((error = construct_vmcs_controls(arch_vmx))) {
         printk("construct_vmcs: construct_vmcs_controls failed\n");
         rc = -EINVAL;
         goto err_out;
     }
+
     /* host selectors */
     if ((error = construct_vmcs_host())) {
         printk("construct_vmcs: construct_vmcs_host failed\n");
         rc = -EINVAL;
         goto err_out;
     }
+
     /* guest selectors */
     if ((error = construct_init_vmcs_guest(regs))) {
         printk("construct_vmcs: construct_vmcs_guest failed\n");
         rc = -EINVAL;
         goto err_out;
     }
+
     if ((error |= __vmwrite(EXCEPTION_BITMAP,
                             MONITOR_DEFAULT_EXCEPTION_BITMAP))) {
         printk("construct_vmcs: setting Exception bitmap failed\n");
@@ -472,12 +483,16 @@ static int construct_vmcs(struct arch_vm
     return 0;
 
 err_out:
-    destroy_vmcs(arch_vmx);
+    vmx_destroy_vmcs(v);
     return rc;
 }
 
-void destroy_vmcs(struct arch_vmx_struct *arch_vmx)
-{
+void vmx_destroy_vmcs(struct vcpu *v)
+{
+    struct arch_vmx_struct *arch_vmx = &v->arch.hvm_vmx;
+
+    vmx_clear_vmcs(v);
+
     free_vmcs(arch_vmx->vmcs);
     arch_vmx->vmcs = NULL;
 
@@ -506,22 +521,20 @@ void vm_resume_fail(unsigned long eflags
 
 void arch_vmx_do_resume(struct vcpu *v)
 {
-    if ( v->arch.hvm_vmx.launch_cpu == smp_processor_id() )
+    if ( v->arch.hvm_vmx.active_cpu == smp_processor_id() )
     {
-        load_vmcs(&v->arch.hvm_vmx, virt_to_maddr(v->arch.hvm_vmx.vmcs));
-        vmx_do_resume(v);
-        reset_stack_and_jump(vmx_asm_do_resume);
+        vmx_load_vmcs(v);
     }
     else
     {
-        vmx_request_clear_vmcs(v);
-        load_vmcs(&v->arch.hvm_vmx, virt_to_maddr(v->arch.hvm_vmx.vmcs));
+        vmx_clear_vmcs(v);
+        vmx_load_vmcs(v);
         vmx_migrate_timers(v);
         vmx_set_host_env(v);
-        vmx_do_resume(v);
-        v->arch.hvm_vmx.launch_cpu = smp_processor_id();
-        reset_stack_and_jump(vmx_asm_do_relaunch);
-    }
+    }
+
+    vmx_do_resume(v);
+    reset_stack_and_jump(vmx_asm_do_vmentry);
 }
 
 void arch_vmx_do_launch(struct vcpu *v)
@@ -529,7 +542,7 @@ void arch_vmx_do_launch(struct vcpu *v)
     int error;
     cpu_user_regs_t *regs = &current->arch.guest_context.user_regs;
 
-    error = construct_vmcs(&v->arch.hvm_vmx, regs);
+    error = construct_vmcs(v, regs);
     if ( error < 0 )
     {
         if (v->vcpu_id == 0) {
@@ -540,7 +553,7 @@ void arch_vmx_do_launch(struct vcpu *v)
         domain_crash_synchronous();
     }
     vmx_do_launch(v);
-    reset_stack_and_jump(vmx_asm_do_launch);
+    reset_stack_and_jump(vmx_asm_do_vmentry);
 }
 
 
@@ -613,17 +626,9 @@ static void vmcs_dump(unsigned char ch)
             }
             printk("\tVCPU %d\n", v->vcpu_id);
 
-            if (v != current) {
-                vcpu_pause(v);
-                __vmptrld(virt_to_maddr(v->arch.hvm_vmx.vmcs));
-            }
-
+            vmx_vmcs_enter(v);
             vmcs_dump_vcpu();
-
-            if (v != current) {
-                __vmptrld(virt_to_maddr(current->arch.hvm_vmx.vmcs));
-                vcpu_unpause(v);
-            }
+            vmx_vmcs_exit(v);
         }
     }
 
diff -r b8f6089cbce3 -r e74c47d073ee xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Tue Jun 13 09:00:32 2006 -0600
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Tue Jun 13 12:12:24 2006 -0600
@@ -38,6 +38,7 @@
 #include <asm/hvm/support.h>
 #include <asm/hvm/vmx/vmx.h>
 #include <asm/hvm/vmx/vmcs.h>
+#include <asm/hvm/vmx/cpu.h>
 #include <asm/shadow.h>
 #if CONFIG_PAGING_LEVELS >= 3
 #include <asm/shadow_64.h>
@@ -66,7 +67,7 @@ void vmx_final_setup_guest(struct vcpu *
 
         /* Initialize monitor page table */
         for_each_vcpu(d, vc)
-            vc->arch.monitor_table = mk_pagetable(0);
+            vc->arch.monitor_table = pagetable_null();
 
         /*
          * Required to do this once per domain
@@ -91,8 +92,7 @@ static void vmx_relinquish_guest_resourc
     {
         if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
             continue;
-        vmx_request_clear_vmcs(v);
-        destroy_vmcs(&v->arch.hvm_vmx);
+        vmx_destroy_vmcs(v);
         free_monitor_pagetable(v);
         kill_timer(&v->arch.hvm_vmx.hlt_timer);
         if ( hvm_apic_support(v->domain) && (VLAPIC(v) != NULL) )
@@ -402,54 +402,10 @@ void vmx_migrate_timers(struct vcpu *v)
         migrate_timer(&(VLAPIC(v)->vlapic_timer), v->processor);
 }
 
-struct vmx_cpu_guest_regs_callback_info {
-    struct vcpu *v;
-    struct cpu_user_regs *regs;
-    unsigned long *crs;
-};
-
-static void vmx_store_cpu_guest_regs(
-    struct vcpu *v, struct cpu_user_regs *regs, unsigned long *crs);
-
-static void vmx_load_cpu_guest_regs(
-    struct vcpu *v, struct cpu_user_regs *regs);
-
-static void vmx_store_cpu_guest_regs_callback(void *data)
-{
-    struct vmx_cpu_guest_regs_callback_info *info = data;
-    vmx_store_cpu_guest_regs(info->v, info->regs, info->crs);
-}
-
-static void vmx_load_cpu_guest_regs_callback(void *data)
-{
-    struct vmx_cpu_guest_regs_callback_info *info = data;
-    vmx_load_cpu_guest_regs(info->v, info->regs);
-}
-
 static void vmx_store_cpu_guest_regs(
     struct vcpu *v, struct cpu_user_regs *regs, unsigned long *crs)
 {
-    if ( v != current )
-    {
-        /* Non-current VCPUs must be paused to get a register snapshot. */
-        ASSERT(atomic_read(&v->pausecnt) != 0);
-
-        if ( v->arch.hvm_vmx.launch_cpu != smp_processor_id() )
-        {
-            /* Get register details from remote CPU. */
-            struct vmx_cpu_guest_regs_callback_info info = {
-                .v = v, .regs = regs, .crs = crs };
-            cpumask_t cpumask = cpumask_of_cpu(v->arch.hvm_vmx.launch_cpu);
-            on_selected_cpus(cpumask, vmx_store_cpu_guest_regs_callback,
-                             &info, 1, 1);
-            return;
-        }
-
-        /* Register details are on this CPU. Load the correct VMCS. */
-        __vmptrld(virt_to_maddr(v->arch.hvm_vmx.vmcs));
-    }
-
-    ASSERT(v->arch.hvm_vmx.launch_cpu == smp_processor_id());
+    vmx_vmcs_enter(v);
 
     if ( regs != NULL )
     {
@@ -471,9 +427,7 @@ static void vmx_store_cpu_guest_regs(
         __vmread(CR4_READ_SHADOW, &crs[4]);
     }
 
-    /* Reload current VCPU's VMCS if it was temporarily unloaded. */
-    if ( (v != current) && hvm_guest(current) )
-        __vmptrld(virt_to_maddr(current->arch.hvm_vmx.vmcs));
+    vmx_vmcs_exit(v);
 }
 
 /*
@@ -517,26 +471,7 @@ static void fixup_vm86_seg_bases(struct 
 
 void vmx_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
 {
-    if ( v != current )
-    {
-        /* Non-current VCPUs must be paused to set the register snapshot. */
-        ASSERT(atomic_read(&v->pausecnt) != 0);
-
-        if ( v->arch.hvm_vmx.launch_cpu != smp_processor_id() )
-        {
-            struct vmx_cpu_guest_regs_callback_info info = {
-                .v = v, .regs = regs };
-            cpumask_t cpumask = cpumask_of_cpu(v->arch.hvm_vmx.launch_cpu);
-            on_selected_cpus(cpumask, vmx_load_cpu_guest_regs_callback,
-                             &info, 1, 1);
-            return;
-        }
-
-        /* Register details are on this CPU. Load the correct VMCS. */
-        __vmptrld(virt_to_maddr(v->arch.hvm_vmx.vmcs));
-    }
-
-    ASSERT(v->arch.hvm_vmx.launch_cpu == smp_processor_id());
+    vmx_vmcs_enter(v);
 
     __vmwrite(GUEST_SS_SELECTOR, regs->ss);
     __vmwrite(GUEST_DS_SELECTOR, regs->ds);
@@ -557,9 +492,7 @@ void vmx_load_cpu_guest_regs(struct vcpu
     __vmwrite(GUEST_CS_SELECTOR, regs->cs);
     __vmwrite(GUEST_RIP, regs->eip);
 
-    /* Reload current VCPU's VMCS if it was temporarily unloaded. */
-    if ( (v != current) && hvm_guest(current) )
-        __vmptrld(virt_to_maddr(current->arch.hvm_vmx.vmcs));
+    vmx_vmcs_exit(v);
 }
 
 int vmx_realmode(struct vcpu *v)
@@ -688,16 +621,19 @@ int start_vmx(void)
 
     set_in_cr4(X86_CR4_VMXE);   /* Enable VMXE */
 
-    if (!(vmcs = alloc_vmcs())) {
+    if (!(vmcs = vmx_alloc_vmcs())) {
         printk("Failed to allocate VMCS\n");
         return 0;
     }
 
     phys_vmcs = (u64) virt_to_maddr(vmcs);
 
-    if (!(__vmxon(phys_vmcs))) {
-        printk("VMXON is done\n");
-    }
+    if (__vmxon(phys_vmcs)) {
+        printk("VMXON failed\n");
+        return 0;
+    }
+
+    printk("VMXON is done\n");
 
     vmx_save_init_msrs();
 
@@ -814,9 +750,7 @@ static void vmx_do_no_device_fault(void)
     }
 }
 
-/* Reserved bits: [31:15], [12:11], [9], [6], [2:1] */
-#define VMX_VCPU_CPUID_L1_RESERVED 0xffff9a46
-
+#define bitmaskof(idx) (1U << ((idx)&31))
 static void vmx_vmexit_do_cpuid(struct cpu_user_regs *regs)
 {
     unsigned int input = (unsigned int)regs->eax;
@@ -833,50 +767,74 @@ static void vmx_vmexit_do_cpuid(struct c
                 (unsigned long)regs->ecx, (unsigned long)regs->edx,
                 (unsigned long)regs->esi, (unsigned long)regs->edi);
 
-    if ( input == 4 )
+    if ( input == CPUID_LEAF_0x4 )
+    {
         cpuid_count(input, count, &eax, &ebx, &ecx, &edx);
+        eax &= NUM_CORES_RESET_MASK;  
+    }
     else
+    {
         cpuid(input, &eax, &ebx, &ecx, &edx);
 
-    if ( input == 1 )
-    {
-        if ( !hvm_apic_support(v->domain) ||
-             !vlapic_global_enabled((VLAPIC(v))) )
+        if ( input == CPUID_LEAF_0x1 )
         {
-            clear_bit(X86_FEATURE_APIC, &edx);
-            /* Since the apic is disabled, avoid any confusion about SMP cpus 
being available */
-            clear_bit(X86_FEATURE_HT, &edx);  /* clear the hyperthread bit */
-            ebx &= 0xFF00FFFF;  /* set the logical processor count to 1 */
-            ebx |= 0x00010000;
-        }
-
-
+            /* mask off reserved bits */
+            ecx &= ~VMX_VCPU_CPUID_L1_ECX_RESERVED; 
+
+            if ( !hvm_apic_support(v->domain) ||
+                 !vlapic_global_enabled((VLAPIC(v))) )
+            {
+                /* Since the apic is disabled, avoid any 
+                confusion about SMP cpus being available */
+
+                clear_bit(X86_FEATURE_APIC, &edx);
+            }
+    
 #if CONFIG_PAGING_LEVELS < 3
-        clear_bit(X86_FEATURE_PAE, &edx);
-        clear_bit(X86_FEATURE_PSE, &edx);
-        clear_bit(X86_FEATURE_PSE36, &edx);
+            edx &= ~(bitmaskof(X86_FEATURE_PAE)  |
+                     bitmaskof(X86_FEATURE_PSE)  |
+                     bitmaskof(X86_FEATURE_PSE36)); 
 #else
-        if ( v->domain->arch.ops->guest_paging_levels == PAGING_L2 )
+            if ( v->domain->arch.ops->guest_paging_levels == PAGING_L2 )
+            {
+                if ( !v->domain->arch.hvm_domain.pae_enabled )
+                    clear_bit(X86_FEATURE_PAE, &edx);
+                clear_bit(X86_FEATURE_PSE, &edx);
+                clear_bit(X86_FEATURE_PSE36, &edx);
+            }
+#endif
+
+            ebx &= NUM_THREADS_RESET_MASK;  
+
+            /* Unsupportable for virtualised CPUs. */
+            ecx &= ~(bitmaskof(X86_FEATURE_VMXE)  |
+                     bitmaskof(X86_FEATURE_EST)   |
+                     bitmaskof(X86_FEATURE_TM2)   |
+                     bitmaskof(X86_FEATURE_CID)   |
+                     bitmaskof(X86_FEATURE_MWAIT) );
+
+            edx &= ~( bitmaskof(X86_FEATURE_HT)   |
+                     bitmaskof(X86_FEATURE_MCA)   |
+                     bitmaskof(X86_FEATURE_MCE)   |
+                     bitmaskof(X86_FEATURE_ACPI)  |
+                     bitmaskof(X86_FEATURE_ACC) );
+        }
+        else if (  ( input == CPUID_LEAF_0x6 ) 
+                || ( input == CPUID_LEAF_0x9 )
+                || ( input == CPUID_LEAF_0xA ))
         {
-            if ( !v->domain->arch.hvm_domain.pae_enabled )
-                clear_bit(X86_FEATURE_PAE, &edx);
-            clear_bit(X86_FEATURE_PSE, &edx);
-            clear_bit(X86_FEATURE_PSE36, &edx);
+            eax = ebx = ecx = edx = 0x0;
+        }
+#ifdef __i386__
+        else if ( input == CPUID_LEAF_0x80000001 )
+        {
+            clear_bit(X86_FEATURE_LAHF_LM & 31, &ecx);
+
+            clear_bit(X86_FEATURE_LM & 31, &edx);
+            clear_bit(X86_FEATURE_SYSCALL & 31, &edx);
         }
 #endif
-
-        /* Unsupportable for virtualised CPUs. */
-        ecx &= ~VMX_VCPU_CPUID_L1_RESERVED; /* mask off reserved bits */
-        clear_bit(X86_FEATURE_VMXE & 31, &ecx);
-        clear_bit(X86_FEATURE_MWAIT & 31, &ecx);
-    }
-#ifdef __i386__
-    else if ( input == 0x80000001 )
-    {
-        /* Mask feature for Intel ia32e or AMD long mode. */
-        clear_bit(X86_FEATURE_LM & 31, &edx);
-    }
-#endif
+    }
 
     regs->eax = (unsigned long) eax;
     regs->ebx = (unsigned long) ebx;
@@ -1223,7 +1181,7 @@ vmx_world_restore(struct vcpu *v, struct
         if(!get_page(mfn_to_page(mfn), v->domain))
                 return 0;
         old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
-        v->arch.guest_table = mk_pagetable((u64)mfn << PAGE_SHIFT);
+        v->arch.guest_table = pagetable_from_pfn(mfn);
         if (old_base_mfn)
              put_page(mfn_to_page(old_base_mfn));
         /*
@@ -1459,7 +1417,7 @@ static int vmx_set_cr0(unsigned long val
         /*
          * Now arch.guest_table points to machine physical.
          */
-        v->arch.guest_table = mk_pagetable((u64)mfn << PAGE_SHIFT);
+        v->arch.guest_table = pagetable_from_pfn(mfn);
         update_pagetables(v);
 
         HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
@@ -1477,7 +1435,7 @@ static int vmx_set_cr0(unsigned long val
         if ( v->arch.hvm_vmx.cpu_cr3 ) {
             put_page(mfn_to_page(get_mfn_from_gpfn(
                       v->arch.hvm_vmx.cpu_cr3 >> PAGE_SHIFT)));
-            v->arch.guest_table = mk_pagetable(0);
+            v->arch.guest_table = pagetable_null();
         }
 
     /*
@@ -1635,7 +1593,7 @@ static int mov_to_cr(int gp, int cr, str
                 domain_crash_synchronous(); /* need to take a clean path */
             }
             old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
-            v->arch.guest_table = mk_pagetable((u64)mfn << PAGE_SHIFT);
+            v->arch.guest_table = pagetable_from_pfn(mfn);
             if (old_base_mfn)
                 put_page(mfn_to_page(old_base_mfn));
             /*
@@ -1690,7 +1648,7 @@ static int mov_to_cr(int gp, int cr, str
                  * Now arch.guest_table points to machine physical.
                  */
 
-                v->arch.guest_table = mk_pagetable((u64)mfn << PAGE_SHIFT);
+                v->arch.guest_table = pagetable_from_pfn(mfn);
                 update_pagetables(v);
 
                 HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
@@ -1970,7 +1928,6 @@ static inline void vmx_vmexit_do_extint(
         __hvm_bug(regs);
 
     vector &= INTR_INFO_VECTOR_MASK;
-    local_irq_disable();
     TRACE_VMEXIT(1,vector);
 
     switch(vector) {
@@ -2065,30 +2022,33 @@ asmlinkage void vmx_vmexit_handler(struc
     struct vcpu *v = current;
     int error;
 
-    if ((error = __vmread(VM_EXIT_REASON, &exit_reason)))
-        __hvm_bug(&regs);
+    error = __vmread(VM_EXIT_REASON, &exit_reason);
+    BUG_ON(error);
 
     perfc_incra(vmexits, exit_reason);
 
-    /* don't bother H/W interrutps */
-    if (exit_reason != EXIT_REASON_EXTERNAL_INTERRUPT &&
-        exit_reason != EXIT_REASON_VMCALL &&
-        exit_reason != EXIT_REASON_IO_INSTRUCTION) 
+    if ( (exit_reason != EXIT_REASON_EXTERNAL_INTERRUPT) &&
+         (exit_reason != EXIT_REASON_VMCALL) &&
+         (exit_reason != EXIT_REASON_IO_INSTRUCTION) )
         HVM_DBG_LOG(DBG_LEVEL_0, "exit reason = %x", exit_reason);
 

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

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