[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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



# 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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.