WARNING - OLD ARCHIVES

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

xen-changelog

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

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 23 Feb 2007 09:50:29 -0800
Delivery-date: Fri, 23 Feb 2007 10:40:02 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User awilliam@xxxxxxxxxxxx
# Date 1172001502 25200
# Node ID d907467f08cd4b55604961f4da4224d3ad5fe9d4
# Parent  04c23c1ef8885cf37b1c17a2f406695272ba036d
# Parent  ecb6cd61a9cfa70be364aace1cb183bae03b04fd
merge with xen-unstable.hg
---
 linux-2.6-xen-sparse/drivers/char/tpm/tpm.c                         | 1222 
---------
 linux-2.6-xen-sparse/include/linux/pfn.h                            |    9 
 tools/libxc/xc_linux_build.c                                        | 1319 
----------
 tools/libxc/xc_load_bin.c                                           |  306 --
 tools/libxc/xc_load_elf.c                                           |  684 
-----
 xen/common/elf.c                                                    |  520 ---
 extras/mini-os/Makefile                                             |    5 
 extras/mini-os/arch/x86/Makefile                                    |    5 
 extras/mini-os/arch/x86/arch.mk                                     |    5 
 extras/mini-os/minios.mk                                            |   17 
 extras/mini-os/xenbus/xenbus.c                                      |    2 
 linux-2.6-xen-sparse/arch/i386/kernel/Makefile                      |    1 
 linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S                    |    4 
 linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c                   |   38 
 linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c                    |   30 
 linux-2.6-xen-sparse/arch/i386/mach-xen/setup.c                     |    2 
 linux-2.6-xen-sparse/arch/i386/mm/fault-xen.c                       |    2 
 linux-2.6-xen-sparse/arch/ia64/xen/util.c                           |   12 
 linux-2.6-xen-sparse/arch/x86_64/kernel/Makefile                    |    1 
 linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c                  |   11 
 linux-2.6-xen-sparse/arch/x86_64/kernel/early_printk-xen.c          |   11 
 linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S                 |    4 
 linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S                  |    7 
 linux-2.6-xen-sparse/arch/x86_64/kernel/mpparse-xen.c               |    2 
 linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c               |    4 
 linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c                 |   15 
 linux-2.6-xen-sparse/arch/x86_64/mm/fault-xen.c                     |    3 
 linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c                      |   26 
 linux-2.6-xen-sparse/drivers/char/tpm/Kconfig                       |    2 
 linux-2.6-xen-sparse/drivers/char/tpm/tpm.h                         |   24 
 linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c                    |    3 
 linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c                  |    6 
 linux-2.6-xen-sparse/drivers/xen/blkback/interface.c                |   14 
 linux-2.6-xen-sparse/drivers/xen/blktap/interface.c                 |   14 
 linux-2.6-xen-sparse/drivers/xen/core/gnttab.c                      |  251 +
 linux-2.6-xen-sparse/drivers/xen/core/smpboot.c                     |    3 
 linux-2.6-xen-sparse/drivers/xen/netback/interface.c                |   26 
 linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c                |   14 
 linux-2.6-xen-sparse/drivers/xen/util.c                             |   31 
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_backend_client.c     |   16 
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h     |    3 
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/irqflags.h       |   17 
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/maddr.h          |   25 
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h           |   53 
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level.h |    7 
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level.h |   27 
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable.h        |   38 
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h         |    3 
 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/irqflags.h     |   17 
 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/maddr.h        |   15 
 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h         |   28 
 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h      |   62 
 linux-2.6-xen-sparse/include/xen/driver_util.h                      |    4 
 linux-2.6-xen-sparse/include/xen/gnttab.h                           |   13 
 patches/linux-2.6.18/x86-elfnote-as-preprocessor-macro.patch        |    5 
 tools/blktap/drivers/Makefile                                       |   16 
 tools/blktap/drivers/block-aio.c                                    |  132 -
 tools/blktap/drivers/block-qcow.c                                   |  563 ++--
 tools/blktap/drivers/block-ram.c                                    |  125 
 tools/blktap/drivers/block-sync.c                                   |   95 
 tools/blktap/drivers/block-vmdk.c                                   |   99 
 tools/blktap/drivers/img2qcow.c                                     |   28 
 tools/blktap/drivers/qcow2raw.c                                     |   75 
 tools/blktap/drivers/tapdisk.c                                      |  372 ++
 tools/blktap/drivers/tapdisk.h                                      |   62 
 tools/blktap/lib/blktaplib.h                                        |   13 
 tools/blktap/lib/xs_api.c                                           |    8 
 tools/check/check_zlib_lib                                          |    4 
 tools/console/daemon/io.c                                           |    8 
 tools/firmware/hvmloader/acpi/build.c                               |   81 
 tools/firmware/hvmloader/acpi/dsdt.asl                              |    8 
 tools/firmware/hvmloader/acpi/dsdt.c                                |  866 
+++---
 tools/firmware/rombios/32bit/Makefile                               |    2 
 tools/firmware/rombios/32bit/tcgbios/Makefile                       |    2 
 tools/ioemu/hw/tpm_tis.c                                            |    3 
 tools/libfsimage/common/fsimage.c                                   |    4 
 tools/libfsimage/common/fsimage.h                                   |    2 
 tools/libfsimage/common/fsimage_grub.c                              |    4 
 tools/libfsimage/common/fsimage_grub.h                              |    2 
 tools/libfsimage/common/fsimage_plugin.c                            |    4 
 tools/libfsimage/common/fsimage_plugin.h                            |    2 
 tools/libfsimage/common/fsimage_priv.h                              |    2 
 tools/libfsimage/ext2fs-lib/ext2fs-lib.c                            |    2 
 tools/libfsimage/ext2fs/fsys_ext2fs.c                               |    2 
 tools/libfsimage/reiserfs/fsys_reiserfs.c                           |    2 
 tools/libfsimage/ufs/fsys_ufs.c                                     |    2 
 tools/libxc/Makefile                                                |    4 
 tools/libxc/xc_dom.h                                                |    2 
 tools/libxc/xc_domain.c                                             |    4 
 tools/libxc/xc_hvm_build.c                                          |    9 
 tools/libxc/xc_linux_restore.c                                      |    6 
 tools/libxc/xc_linux_save.c                                         |    8 
 tools/libxc/xc_pagetab.c                                            |    4 
 tools/libxc/xc_private.c                                            |   20 
 tools/libxc/xg_private.h                                            |   84 
 tools/pygrub/src/fsimage/fsimage.c                                  |   14 
 tools/python/xen/xend/XendDomainInfo.py                             |   21 
 tools/python/xen/xend/image.py                                      |    1 
 tools/security/xensec_ezpolicy                                      |    6 
 tools/xcutils/readnotes.c                                           |  138 -
 xen/acm/acm_simple_type_enforcement_hooks.c                         |   18 
 xen/arch/ia64/xen/domain.c                                          |   10 
 xen/arch/ia64/xen/mm.c                                              |    4 
 xen/arch/x86/domain_build.c                                         |    4 
 xen/arch/x86/hvm/io.c                                               |    5 
 xen/arch/x86/hvm/platform.c                                         |   31 
 xen/arch/x86/hvm/svm/svm.c                                          |   32 
 xen/arch/x86/hvm/vlapic.c                                           |    2 
 xen/arch/x86/hvm/vmx/vmx.c                                          |   18 
 xen/arch/x86/mm.c                                                   |   36 
 xen/arch/x86/mm/shadow/common.c                                     |  177 -
 xen/arch/x86/mm/shadow/multi.c                                      |  179 -
 xen/arch/x86/mm/shadow/private.h                                    |   17 
 xen/arch/x86/mm/shadow/types.h                                      |    1 
 xen/arch/x86/traps.c                                                |   29 
 xen/arch/x86/x86_32/seg_fixup.c                                     |    5 
 xen/common/compat/grant_table.c                                     |    3 
 xen/common/grant_table.c                                            |  502 ++-
 xen/common/libelf/libelf-dominfo.c                                  |  119 
 xen/common/libelf/libelf-tools.c                                    |   11 
 xen/include/asm-ia64/bug.h                                          |    6 
 xen/include/asm-ia64/grant_table.h                                  |   43 
 xen/include/asm-powerpc/bug.h                                       |    6 
 xen/include/asm-powerpc/grant_table.h                               |    2 
 xen/include/asm-x86/bug.h                                           |   13 
 xen/include/asm-x86/grant_table.h                                   |    6 
 xen/include/asm-x86/hvm/io.h                                        |    1 
 xen/include/asm-x86/processor.h                                     |    5 
 xen/include/asm-x86/x86_32/bug.h                                    |   19 
 xen/include/asm-x86/x86_64/bug.h                                    |   19 
 xen/include/asm-x86/x86_64/page.h                                   |   14 
 xen/include/public/arch-ia64.h                                      |    2 
 xen/include/public/arch-powerpc.h                                   |    2 
 xen/include/public/arch-x86/xen.h                                   |    2 
 xen/include/public/elfnote.h                                        |    8 
 xen/include/public/grant_table.h                                    |   19 
 xen/include/public/hvm/save.h                                       |   13 
 xen/include/public/libelf.h                                         |    3 
 xen/include/xen/grant_table.h                                       |   38 
 xen/include/xen/lib.h                                               |    5 
 xen/include/xen/sched.h                                             |    9 
 141 files changed, 3077 insertions(+), 6260 deletions(-)

diff -r 04c23c1ef888 -r d907467f08cd extras/mini-os/Makefile
--- a/extras/mini-os/Makefile   Sun Feb 18 16:13:13 2007 -0700
+++ b/extras/mini-os/Makefile   Tue Feb 20 12:58:22 2007 -0700
@@ -44,10 +44,6 @@ ARCH_LINKS =
 # This can be overwritten from arch specific rules.
 EXTRA_INC =
 
-# Special build dependencies.
-# Build all after touching this/these file(s) (see minios.mk)
-SPEC_DEPENDS = minios.mk
-
 # Include the architecture family's special makerules.
 # This must be before include minios.mk!
 include $(TARGET_ARCH_DIR)/arch.mk
@@ -57,7 +53,6 @@ include minios.mk
 
 # Define some default flags for linking.
 LDLIBS := 
-LDFLAGS := 
 LDARCHLIB := -L$(TARGET_ARCH_DIR) -l$(ARCH_LIB_NAME)
 LDFLAGS_FINAL := -N -T $(TARGET_ARCH_DIR)/minios-$(TARGET_ARCH).lds
 
diff -r 04c23c1ef888 -r d907467f08cd extras/mini-os/arch/x86/Makefile
--- a/extras/mini-os/arch/x86/Makefile  Sun Feb 18 16:13:13 2007 -0700
+++ b/extras/mini-os/arch/x86/Makefile  Tue Feb 20 12:58:22 2007 -0700
@@ -2,9 +2,6 @@
 # x86 architecture specific makefiles.
 # It's is used for x86_32, x86_32y and x86_64
 #
-
-# Rebuild all after touching this/these extra file(s) (see mini-os.mk)
-SPEC_DEP = arch.mk
 
 # include arch.mk has to be before mini-os.mk!
 include arch.mk
@@ -25,5 +22,5 @@ all: $(ARCH_LIB)
        $(AR) rv $(ARCH_LIB) $(ARCH_OBJS)
 
 clean:
-       rm -f $(ARCH_LIB) $(ARCH_OBJS)
+       rm -f $(ARCH_LIB) $(ARCH_OBJS) $(HEAD_ARCH_OBJ)
 
diff -r 04c23c1ef888 -r d907467f08cd extras/mini-os/arch/x86/arch.mk
--- a/extras/mini-os/arch/x86/arch.mk   Sun Feb 18 16:13:13 2007 -0700
+++ b/extras/mini-os/arch/x86/arch.mk   Tue Feb 20 12:58:22 2007 -0700
@@ -6,6 +6,7 @@ ifeq ($(TARGET_ARCH),x86_32)
 ifeq ($(TARGET_ARCH),x86_32)
 ARCH_CFLAGS  := -m32 -march=i686
 ARCH_LDFLAGS := -m elf_i386
+ARCH_ASFLAGS := -m32
 EXTRA_INC += $(TARGET_ARCH_FAM)/$(TARGET_ARCH)
 EXTRA_SRC += arch/$(EXTRA_INC)
 endif
@@ -19,10 +20,10 @@ endif
 
 ifeq ($(TARGET_ARCH),x86_64)
 ARCH_CFLAGS := -m64 -mno-red-zone -fpic -fno-reorder-blocks
-ARCH_CFLAGS := -fno-asynchronous-unwind-tables
+ARCH_CFLAGS += -fno-asynchronous-unwind-tables
+ARCH_ASFLAGS := -m64
 ARCH_LDFLAGS := -m elf_x86_64
 EXTRA_INC += $(TARGET_ARCH_FAM)/$(TARGET_ARCH)
 EXTRA_SRC += arch/$(EXTRA_INC)
 endif
 
-
diff -r 04c23c1ef888 -r d907467f08cd extras/mini-os/minios.mk
--- a/extras/mini-os/minios.mk  Sun Feb 18 16:13:13 2007 -0700
+++ b/extras/mini-os/minios.mk  Tue Feb 20 12:58:22 2007 -0700
@@ -11,6 +11,7 @@ DEF_CFLAGS += -D__XEN_INTERFACE_VERSION_
 DEF_CFLAGS += -D__XEN_INTERFACE_VERSION__=$(XEN_INTERFACE_VERSION)
 
 DEF_ASFLAGS = -D__ASSEMBLY__
+DEF_LDFLAGS =
 
 ifeq ($(debug),y)
 DEF_CFLAGS += -g
@@ -23,21 +24,27 @@ endif
 # ARCH_... flags may be defined in arch/$(TARGET_ARCH_FAM/rules.mk
 CFLAGS := $(DEF_CFLAGS) $(ARCH_CFLAGS)
 ASFLAGS := $(DEF_ASFLAGS) $(ARCH_ASFLAGS)
+LDFLAGS := $(DEF_LDFLAGS) $(ARCH_LDFLAGS)
 
 # The path pointing to the architecture specific header files.
-ARCH_SPEC_INC := $(MINI-OS_ROOT)/include/$(TARGET_ARCH_FAM)
+ARCH_INC := $(MINI-OS_ROOT)/include/$(TARGET_ARCH_FAM)
+
+# Special build dependencies.
+# Rebuild all after touching this/these file(s)
+EXTRA_DEPS = $(MINI-OS_ROOT)/minios.mk \
+               $(MINI-OS_ROOT)/$(TARGET_ARCH_DIR)/arch.mk
 
 # Find all header files for checking dependencies.
 HDRS := $(wildcard $(MINI-OS_ROOT)/include/*.h)
 HDRS += $(wildcard $(MINI-OS_ROOT)/include/xen/*.h)
-HDRS += $(wildcard $(ARCH_SPEC_INC)/*.h)
+HDRS += $(wildcard $(ARCH_INC)/*.h)
 # For special wanted header directories.
 extra_heads := $(foreach dir,$(EXTRA_INC),$(wildcard $(dir)/*.h))
 HDRS += $(extra_heads)
 
 # Add the special header directories to the include paths.
 extra_incl := $(foreach dir,$(EXTRA_INC),-I$(MINI-OS_ROOT)/include/$(dir))
-override CPPFLAGS := -I$(MINI-OS_ROOT)/include $(CPPFLAGS) -I$(ARCH_SPEC_INC)  
$(extra_incl)
+override CPPFLAGS := -I$(MINI-OS_ROOT)/include $(CPPFLAGS) -I$(ARCH_INC)       
$(extra_incl)
 
 # The name of the architecture specific library.
 # This is on x86_32: libx86_32.a
@@ -51,10 +58,10 @@ HEAD_OBJ := $(TARGET_ARCH_DIR)/$(HEAD_AR
 HEAD_OBJ := $(TARGET_ARCH_DIR)/$(HEAD_ARCH_OBJ)
 
 
-%.o: %.c $(HDRS) Makefile $(SPEC_DEPENDS)
+%.o: %.c $(HDRS) Makefile $(EXTRA_DEPS)
        $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
 
-%.o: %.S $(HDRS) Makefile $(SPEC_DEPENDS)
+%.o: %.S $(HDRS) Makefile $(EXTRA_DEPS)
        $(CC) $(ASFLAGS) $(CPPFLAGS) -c $< -o $@
 
 
diff -r 04c23c1ef888 -r d907467f08cd extras/mini-os/xenbus/xenbus.c
--- a/extras/mini-os/xenbus/xenbus.c    Sun Feb 18 16:13:13 2007 -0700
+++ b/extras/mini-os/xenbus/xenbus.c    Tue Feb 20 12:58:22 2007 -0700
@@ -210,7 +210,7 @@ static int allocate_xenbus_id(void)
     }
     nr_live_reqs++;
     req_info[o_probe].in_use = 1;
-    probe = o_probe + 1;
+    probe = (o_probe + 1) % NR_REQS;
     spin_unlock(&req_lock);
     init_waitqueue_head(&req_info[o_probe].waitq);
 
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/arch/i386/kernel/Makefile
--- a/linux-2.6-xen-sparse/arch/i386/kernel/Makefile    Sun Feb 18 16:13:13 
2007 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/Makefile    Tue Feb 20 12:58:22 
2007 -0700
@@ -98,4 +98,5 @@ obj-y := $(call filterxen, $(obj-y), $(n
 obj-y := $(call filterxen, $(obj-y), $(n-obj-xen))
 obj-y := $(call cherrypickxen, $(obj-y))
 extra-y := $(call cherrypickxen, $(extra-y))
+%/head-xen.o %/head-xen.s: EXTRA_AFLAGS :=
 endif
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S
--- a/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S  Sun Feb 18 16:13:13 
2007 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S  Tue Feb 20 12:58:22 
2007 -0700
@@ -11,6 +11,8 @@
 #include <asm/asm-offsets.h>
 #include <xen/interface/xen.h>
 #include <xen/interface/elfnote.h>
+
+#define _PAGE_PRESENT 0x1
 
 /*
  * References to members of the new_cpu_data structure.
@@ -198,7 +200,9 @@ ENTRY(cpu_gdt_table)
        ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,       .asciz, 
"writable_page_tables|writable_descriptor_tables|auto_translated_physmap|pae_pgdir_above_4gb|supervisor_mode_kernel")
 #ifdef CONFIG_X86_PAE
        ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz, "yes")
+       ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID,   .quad,  
_PAGE_PRESENT,_PAGE_PRESENT)
 #else
        ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz, "no")
+       ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID,   .long,  
_PAGE_PRESENT,_PAGE_PRESENT)
 #endif
        ELFNOTE(Xen, XEN_ELFNOTE_LOADER,         .asciz, "generic")
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Sun Feb 18 16:13:13 
2007 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Tue Feb 20 12:58:22 
2007 -0700
@@ -1034,8 +1034,16 @@ e820_all_mapped(unsigned long s, unsigne
        u64 start = s;
        u64 end = e;
        int i;
+
+#ifndef CONFIG_XEN
        for (i = 0; i < e820.nr_map; i++) {
                struct e820entry *ei = &e820.map[i];
+#else
+       if (!is_initial_xendomain())
+               return 0;
+       for (i = 0; i < machine_e820.nr_map; ++i) {
+               const struct e820entry *ei = &machine_e820.map[i];
+#endif
                if (type && ei->type != type)
                        continue;
                /* is the region (part) in overlap with the current region ?*/
@@ -1505,9 +1513,6 @@ e820_setup_gap(struct e820entry *e820, i
  */
 static int __init request_standard_resources(void)
 {
-#ifdef CONFIG_XEN
-       struct xen_memory_map memmap;
-#endif
        int           i;
 
        /* Nothing to do if not running in dom0. */
@@ -1516,13 +1521,6 @@ static int __init request_standard_resou
 
        printk("Setting up standard PCI resources\n");
 #ifdef CONFIG_XEN
-       memmap.nr_entries = E820MAX;
-       set_xen_guest_handle(memmap.buffer, machine_e820.map);
-
-       if (HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap))
-               BUG();
-       machine_e820.nr_map = memmap.nr_entries;
-
        legacy_init_iomem_resources(machine_e820.map, machine_e820.nr_map,
                                    &code_resource, &data_resource);
 #else
@@ -1546,12 +1544,22 @@ subsys_initcall(request_standard_resourc
 
 static void __init register_memory(void)
 {
-
 #ifdef CONFIG_XEN
-       e820_setup_gap(machine_e820.map, machine_e820.nr_map);
-#else
-       e820_setup_gap(e820.map, e820.nr_map);
-#endif
+       if (is_initial_xendomain()) {
+               struct xen_memory_map memmap;
+
+               memmap.nr_entries = E820MAX;
+               set_xen_guest_handle(memmap.buffer, machine_e820.map);
+
+               if (HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap))
+                       BUG();
+
+               machine_e820.nr_map = memmap.nr_entries;
+               e820_setup_gap(machine_e820.map, machine_e820.nr_map);
+       }
+       else
+#endif
+               e820_setup_gap(e820.map, e820.nr_map);
 }
 
 #ifdef CONFIG_MCA
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c  Sun Feb 18 16:13:13 
2007 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c  Tue Feb 20 12:58:22 
2007 -0700
@@ -222,8 +222,7 @@ void init_cpu_khz(void)
 void init_cpu_khz(void)
 {
        u64 __cpu_khz = 1000000ULL << 32;
-       struct vcpu_time_info *info;
-       info = &HYPERVISOR_shared_info->vcpu_info[0].time;
+       struct vcpu_time_info *info = &vcpu_info(0)->time;
        do_div(__cpu_khz, info->tsc_to_system_mul);
        if (info->tsc_shift < 0)
                cpu_khz = __cpu_khz << -info->tsc_shift;
@@ -293,14 +292,13 @@ static void update_wallclock(void)
  * Reads a consistent set of time-base values from Xen, into a shadow data
  * area.
  */
-static void get_time_values_from_xen(void)
-{
-       shared_info_t           *s = HYPERVISOR_shared_info;
+static void get_time_values_from_xen(int cpu)
+{
        struct vcpu_time_info   *src;
        struct shadow_time_info *dst;
 
-       src = &s->vcpu_info[smp_processor_id()].time;
-       dst = &per_cpu(shadow_time, smp_processor_id());
+       src = &vcpu_info(cpu)->time;
+       dst = &per_cpu(shadow_time, cpu);
 
        do {
                dst->version = src->version;
@@ -320,7 +318,7 @@ static inline int time_values_up_to_date
        struct vcpu_time_info   *src;
        struct shadow_time_info *dst;
 
-       src = &HYPERVISOR_shared_info->vcpu_info[cpu].time;
+       src = &vcpu_info(cpu)->time;
        dst = &per_cpu(shadow_time, cpu);
 
        rmb();
@@ -412,7 +410,7 @@ void do_gettimeofday(struct timeval *tv)
                         * overflowed). Detect that and recalculate
                         * with fresh values.
                         */
-                       get_time_values_from_xen();
+                       get_time_values_from_xen(cpu);
                        continue;
                }
        } while (read_seqretry(&xtime_lock, seq) ||
@@ -456,7 +454,7 @@ int do_settimeofday(struct timespec *tv)
                nsec = tv->tv_nsec - get_nsec_offset(shadow);
                if (time_values_up_to_date(cpu))
                        break;
-               get_time_values_from_xen();
+               get_time_values_from_xen(cpu);
        }
        sec = tv->tv_sec;
        __normalize_time(&sec, &nsec);
@@ -551,7 +549,7 @@ unsigned long long monotonic_clock(void)
                barrier();
                time = shadow->system_timestamp + get_nsec_offset(shadow);
                if (!time_values_up_to_date(cpu))
-                       get_time_values_from_xen();
+                       get_time_values_from_xen(cpu);
                barrier();
        } while (local_time_version != shadow->version);
 
@@ -621,7 +619,7 @@ irqreturn_t timer_interrupt(int irq, voi
        write_seqlock(&xtime_lock);
 
        do {
-               get_time_values_from_xen();
+               get_time_values_from_xen(cpu);
 
                /* Obtain a consistent snapshot of elapsed wallclock cycles. */
                delta = delta_cpu =
@@ -708,7 +706,7 @@ irqreturn_t timer_interrupt(int irq, voi
        if (delta_cpu > 0) {
                do_div(delta_cpu, NS_PER_TICK);
                per_cpu(processed_system_time, cpu) += delta_cpu * NS_PER_TICK;
-               if (user_mode(regs))
+               if (user_mode_vm(regs))
                        account_user_time(current, (cputime_t)delta_cpu);
                else
                        account_system_time(current, HARDIRQ_OFFSET,
@@ -722,7 +720,7 @@ irqreturn_t timer_interrupt(int irq, voi
        /* Local timer processing (see update_process_times()). */
        run_local_timers();
        if (rcu_pending(cpu))
-               rcu_check_callbacks(cpu, user_mode(regs));
+               rcu_check_callbacks(cpu, user_mode_vm(regs));
        scheduler_tick();
        run_posix_cpu_timers(current);
        profile_tick(CPU_PROFILING, regs);
@@ -921,7 +919,7 @@ void __init time_init(void)
                return;
        }
 #endif
-       get_time_values_from_xen();
+       get_time_values_from_xen(0);
 
        processed_system_time = per_cpu(shadow_time, 0).system_timestamp;
        per_cpu(processed_system_time, 0) = processed_system_time;
@@ -1029,7 +1027,7 @@ void time_resume(void)
 {
        init_cpu_khz();
 
-       get_time_values_from_xen();
+       get_time_values_from_xen(0);
 
        processed_system_time = per_cpu(shadow_time, 0).system_timestamp;
        per_cpu(processed_system_time, 0) = processed_system_time;
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/arch/i386/mach-xen/setup.c
--- a/linux-2.6-xen-sparse/arch/i386/mach-xen/setup.c   Sun Feb 18 16:13:13 
2007 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/mach-xen/setup.c   Tue Feb 20 12:58:22 
2007 -0700
@@ -67,7 +67,7 @@ char * __init machine_specific_memory_se
        if ( rc == -ENOSYS ) {
                memmap.nr_entries = 1;
                map[0].addr = 0ULL;
-               map[0].size = PFN_PHYS(xen_start_info->nr_pages);
+               map[0].size = PFN_PHYS((unsigned long 
long)xen_start_info->nr_pages);
                /* 8MB slack (to balance backend allocations). */
                map[0].size += 8ULL << 20;
                map[0].type = E820_RAM;
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/arch/i386/mm/fault-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/fault-xen.c     Sun Feb 18 16:13:13 
2007 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/mm/fault-xen.c     Tue Feb 20 12:58:22 
2007 -0700
@@ -731,7 +731,7 @@ do_sigbus:
        force_sig_info_fault(SIGBUS, BUS_ADRERR, address, tsk);
 }
 
-#ifndef CONFIG_X86_PAE
+#if !HAVE_SHARED_KERNEL_PMD
 void vmalloc_sync_all(void)
 {
        /*
diff -r 04c23c1ef888 -r d907467f08cd linux-2.6-xen-sparse/arch/ia64/xen/util.c
--- a/linux-2.6-xen-sparse/arch/ia64/xen/util.c Sun Feb 18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/util.c Tue Feb 20 12:58:22 2007 -0700
@@ -95,18 +95,6 @@ void free_vm_area(struct vm_struct *area
 }
 EXPORT_SYMBOL_GPL(free_vm_area);
 
-void lock_vm_area(struct vm_struct *area)
-{
-       // nothing
-}
-EXPORT_SYMBOL_GPL(lock_vm_area);
-
-void unlock_vm_area(struct vm_struct *area)
-{
-       // nothing
-}
-EXPORT_SYMBOL_GPL(unlock_vm_area);
-
 /*
  * Local variables:
  *  c-file-style: "linux"
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/arch/x86_64/kernel/Makefile
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/Makefile  Sun Feb 18 16:13:13 
2007 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/Makefile  Tue Feb 20 12:58:22 
2007 -0700
@@ -72,4 +72,5 @@ obj-y := $(call filterxen, $(obj-y), $(n
 obj-y := $(call filterxen, $(obj-y), $(n-obj-xen))
 obj-y := $(call cherrypickxen, $(obj-y))
 extra-y := $(call cherrypickxen, $(extra-y))
+%/head-xen.o %/head-xen.s: EXTRA_AFLAGS :=
 endif
diff -r 04c23c1ef888 -r d907467f08cd 
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        Sun Feb 18 
16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c        Tue Feb 20 
12:58:22 2007 -0700
@@ -127,8 +127,19 @@ int __init e820_all_mapped(unsigned long
 int __init e820_all_mapped(unsigned long start, unsigned long end, unsigned 
type)
 {
        int i;
+
+#ifndef CONFIG_XEN
        for (i = 0; i < e820.nr_map; i++) {
                struct e820entry *ei = &e820.map[i];
+#else
+       extern struct e820map machine_e820;
+
+       if (!is_initial_xendomain())
+               return 0;
+       for (i = 0; i < machine_e820.nr_map; i++) {
+               const struct e820entry *ei = &machine_e820.map[i];
+#endif
+
                if (type && ei->type != type)
                        continue;
                /* is the region (part) in overlap with the current region ?*/
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/arch/x86_64/kernel/early_printk-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/early_printk-xen.c        Sun Feb 
18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/early_printk-xen.c        Tue Feb 
20 12:58:22 2007 -0700
@@ -18,9 +18,8 @@
 #define VGABASE                ((void __iomem *)0xffffffff800b8000UL)
 #endif
 
+#ifndef CONFIG_XEN
 static int max_ypos = 25, max_xpos = 80;
-
-#ifndef CONFIG_XEN
 static int current_ypos = 25, current_xpos = 0; 
 
 static void early_vga_write(struct console *con, const char *str, unsigned n)
@@ -154,10 +153,6 @@ static __init void early_serial_init(cha
 
 #else /* CONFIG_XEN */
 
-#undef SCREEN_INFO
-#define SCREEN_INFO screen_info
-extern struct screen_info screen_info;
-
 static void
 early_serial_write(struct console *con, const char *s, unsigned count)
 {
@@ -273,11 +268,13 @@ int __init setup_early_printk(char *opt)
                early_serial_init(buf);
                early_console = &early_serial_console;
        } else if (!strncmp(buf, "vga", 3)
+#ifndef CONFIG_XEN
                   && SCREEN_INFO.orig_video_isVGA == 1) {
                max_xpos = SCREEN_INFO.orig_video_cols;
                max_ypos = SCREEN_INFO.orig_video_lines;
-#ifndef CONFIG_XEN
                current_ypos = SCREEN_INFO.orig_y;
+#else
+                  || !strncmp(buf, "xen", 3)) {
 #endif
                early_console = &early_vga_console;
        } else if (!strncmp(buf, "simnow", 6)) {
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S       Sun Feb 18 
16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S       Tue Feb 20 
12:58:22 2007 -0700
@@ -32,9 +32,6 @@
  */
 
 #define ASSEMBLY 1
-#ifdef CONFIG_DEBUG_INFO
-#undef CONFIG_DEBUG_INFO
-#endif
 #include <linux/linkage.h>
 #include <asm/segment.h>
 #include <asm/smp.h>
@@ -537,6 +534,7 @@ END(stub_rt_sigreturn)
  */ 
 
 retint_check:
+       CFI_DEFAULT_STACK
        movl threadinfo_flags(%rcx),%edx
        andl %edi,%edx
        CFI_REMEMBER_STATE
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S        Sun Feb 18 
16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S        Tue Feb 20 
12:58:22 2007 -0700
@@ -25,7 +25,9 @@
 
 #include <xen/interface/elfnote.h>
 
-       .text
+#define _PAGE_PRESENT 0x1
+
+       .section .bootstrap.text, "ax", @progbits
        .code64
 #define VIRT_ENTRY_OFFSET 0x0
 .org VIRT_ENTRY_OFFSET
@@ -49,7 +51,7 @@ ENTRY(_stext)
 #define NEXT_PAGE(name) \
        $page = $page + 1; \
        .org $page * 0x1000; \
-       phys_/**/name = $page * 0x1000 + __PHYSICAL_START; \
+       phys_##name = $page * 0x1000 + __PHYSICAL_START; \
 ENTRY(name)
 
 NEXT_PAGE(init_level4_pgt)
@@ -181,5 +183,6 @@ ENTRY(empty_zero_page)
 #endif /* !CONFIG_XEN_COMPAT_030002 */
        ELFNOTE(Xen, XEN_ELFNOTE_ENTRY,          .quad,  startup_64)
        ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .quad,  hypercall_page)
+       ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID,   .quad,  
_PAGE_PRESENT,_PAGE_PRESENT)
        ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,       .asciz, 
"writable_page_tables|writable_descriptor_tables|auto_translated_physmap|pae_pgdir_above_4gb|supervisor_mode_kernel")
        ELFNOTE(Xen, XEN_ELFNOTE_LOADER,         .asciz, "generic")
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/arch/x86_64/kernel/mpparse-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/mpparse-xen.c     Sun Feb 18 
16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/mpparse-xen.c     Tue Feb 20 
12:58:22 2007 -0700
@@ -170,7 +170,7 @@ static void __cpuinit MP_processor_info 
        cpu_set(cpu, cpu_present_map);
 }
 #else
-void __init MP_processor_info (struct mpc_config_processor *m)
+static void __cpuinit MP_processor_info (struct mpc_config_processor *m)
 {
        num_processors++;
 }
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c     Sun Feb 18 
16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c     Tue Feb 20 
12:58:22 2007 -0700
@@ -499,8 +499,6 @@ __switch_to(struct task_struct *prev_p, 
         * This is basically '__unlazy_fpu', except that we queue a
         * multicall to indicate FPU task switch, rather than
         * synchronously trapping to Xen.
-        * This must be here to ensure both math_state_restore() and
-        * kernel_fpu_begin() work consistently. 
         * The AMD workaround requires it to be after DS reload, or
         * after DS has been cleared, which we do in __prepare_arch_switch.
         */
@@ -579,7 +577,7 @@ __switch_to(struct task_struct *prev_p, 
                HYPERVISOR_set_segment_base(SEGBASE_GS_USER, next->gs); 
 
        /* 
-        * Switch the PDA and FPU contexts.
+        * Switch the PDA context.
         */
        prev->userrsp = read_pda(oldrsp); 
        write_pda(oldrsp, next->userrsp); 
diff -r 04c23c1ef888 -r d907467f08cd 
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       Sun Feb 18 
16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c       Tue Feb 20 
12:58:22 2007 -0700
@@ -90,9 +90,6 @@ extern char hypercall_page[PAGE_SIZE];
 extern char hypercall_page[PAGE_SIZE];
 EXPORT_SYMBOL(hypercall_page);
 
-/* Allows setting of maximum possible memory size  */
-unsigned long xen_override_max_pfn;
-
 static int xen_panic_event(struct notifier_block *, unsigned long, void *);
 static struct notifier_block xen_panic_block = {
        xen_panic_event, NULL, 0 /* try to go last */
@@ -580,13 +577,13 @@ static void discover_ebda(void)
        if (ebda_size > 64*1024)
                ebda_size = 64*1024;
 }
+#else
+#define discover_ebda() ((void)0)
 #endif
 
 void __init setup_arch(char **cmdline_p)
 {
 #ifdef CONFIG_XEN
-       struct xen_memory_map memmap;
-
        /* Register a call for panic conditions. */
        atomic_notifier_chain_register(&panic_notifier_list, &xen_panic_block);
 
@@ -675,9 +672,7 @@ void __init setup_arch(char **cmdline_p)
 
        check_efer();
 
-#ifndef CONFIG_XEN
        discover_ebda();
-#endif
 
        init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT));
 
@@ -719,7 +714,6 @@ void __init setup_arch(char **cmdline_p)
        /* reserve ebda region */
        if (ebda_addr)
                reserve_bootmem_generic(ebda_addr, ebda_size);
-#endif
 
 #ifdef CONFIG_SMP
        /*
@@ -731,6 +725,7 @@ void __init setup_arch(char **cmdline_p)
 
        /* Reserve SMP trampoline */
        reserve_bootmem_generic(SMP_TRAMPOLINE_BASE, PAGE_SIZE);
+#endif
 #endif
 
 #ifdef CONFIG_ACPI_SLEEP
@@ -895,6 +890,8 @@ void __init setup_arch(char **cmdline_p)
        probe_roms();
 #ifdef CONFIG_XEN
        if (is_initial_xendomain()) {
+               struct xen_memory_map memmap;
+
                memmap.nr_entries = E820MAX;
                set_xen_guest_handle(memmap.buffer, machine_e820.map);
 
@@ -1378,9 +1375,7 @@ void __cpuinit identify_cpu(struct cpuin
                        c->x86_capability[2] = cpuid_edx(0x80860001);
        }
 
-#ifdef CONFIG_X86_XEN_GENAPIC
        c->apicid = phys_pkg_id(0);
-#endif
 
        /*
         * Vendor-specific initialization.  In this section we
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/arch/x86_64/mm/fault-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/mm/fault-xen.c   Sun Feb 18 16:13:13 
2007 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/mm/fault-xen.c   Tue Feb 20 12:58:22 
2007 -0700
@@ -411,8 +411,7 @@ asmlinkage void __kprobes do_page_fault(
        prefetchw(&mm->mmap_sem);
 
        /* get the address */
-       address = HYPERVISOR_shared_info->vcpu_info[
-               smp_processor_id()].arch.cr2;
+       address = current_vcpu_info()->arch.cr2;
 
        info.si_code = SEGV_MAPERR;
 
diff -r 04c23c1ef888 -r d907467f08cd 
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    Sun Feb 18 16:13:13 
2007 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c    Tue Feb 20 12:58:22 
2007 -0700
@@ -77,7 +77,7 @@ extern unsigned long start_pfn;
        (((mfn_to_pfn((addr) >> PAGE_SHIFT)) << PAGE_SHIFT) +   \
        __START_KERNEL_map)))
 
-static void early_make_page_readonly(void *va, unsigned int feature)
+static void __meminit early_make_page_readonly(void *va, unsigned int feature)
 {
        unsigned long addr, _va = (unsigned long)va;
        pte_t pte, *ptep;
@@ -279,8 +279,8 @@ static __init void set_pte_phys(unsigned
        __flush_tlb_one(vaddr);
 }
 
-static void set_pte_phys_ma(unsigned long vaddr,
-                        unsigned long phys, pgprot_t prot)
+static __init void set_pte_phys_ma(unsigned long vaddr,
+                                  unsigned long phys, pgprot_t prot)
 {
        pgd_t *pgd;
        pud_t *pud;
@@ -361,9 +361,10 @@ __set_fixmap (enum fixed_addresses idx, 
 }
 
 /*
- * At this point it only supports vsyscall area.
+ * This only supports vsyscall area.
  */
-void __set_fixmap_user (enum fixed_addresses idx, unsigned long phys, pgprot_t 
prot)
+void __init
+__set_fixmap_user (enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
 {
        unsigned long address = __fix_to_virt(idx);
 
@@ -376,15 +377,6 @@ void __set_fixmap_user (enum fixed_addre
 }
 
 unsigned long __initdata table_start, table_end; 
-
-unsigned long get_machine_pfn(unsigned long addr)
-{
-       pud_t* pud = pud_offset_k(NULL, addr);
-       pmd_t* pmd = pmd_offset(pud, addr);
-       pte_t *pte = pte_offset_kernel(pmd, addr);
-
-       return pte_mfn(*pte);
-} 
 
 static __meminit void *alloc_static_page(unsigned long *phys)
 {
@@ -531,10 +523,6 @@ void __init xen_init_pt(void)
 {
        unsigned long addr, *page;
 
-       memset((void *)init_level4_pgt,   0, PAGE_SIZE);
-       memset((void *)level3_kernel_pgt, 0, PAGE_SIZE);
-       memset((void *)level2_kernel_pgt, 0, PAGE_SIZE);
-
        /* Find the initial pte page that was built for us. */
        page = (unsigned long *)xen_start_info->pt_base;
        addr = page[pgd_index(__START_KERNEL_map)];
@@ -595,7 +583,7 @@ void __init xen_init_pt(void)
                mk_kernel_pgd(__pa_symbol(level3_user_pgt)));
 }
 
-void __init extend_init_mapping(unsigned long tables_space)
+static void __init extend_init_mapping(unsigned long tables_space)
 {
        unsigned long va = __START_KERNEL_map;
        unsigned long phys, addr, *pte_page;
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/drivers/char/tpm/Kconfig
--- a/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig     Sun Feb 18 16:13:13 
2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig     Tue Feb 20 12:58:22 
2007 -0700
@@ -22,7 +22,7 @@ config TCG_TPM
 
 config TCG_TIS
        tristate "TPM Interface Specification 1.2 Interface"
-       depends on TCG_TPM
+       depends on TCG_TPM && PNPACPI
        ---help---
          If you have a TPM security chip that is compliant with the
          TCG TIS 1.2 TPM specification say Yes and it will be accessible
diff -r 04c23c1ef888 -r d907467f08cd linux-2.6-xen-sparse/drivers/char/tpm/tpm.c
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm.c       Sun Feb 18 16:13:13 
2007 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,1222 +0,0 @@
-/*
- * Copyright (C) 2004 IBM Corporation
- *
- * Authors:
- * Leendert van Doorn <leendert@xxxxxxxxxxxxxx>
- * Dave Safford <safford@xxxxxxxxxxxxxx>
- * Reiner Sailer <sailer@xxxxxxxxxxxxxx>
- * Kylene Hall <kjhall@xxxxxxxxxx>
- *
- * Maintained by: <tpmdd_devel@xxxxxxxxxxxxxxxxxxxxx>
- *
- * Device driver for TCG/TCPA TPM (trusted platform module).
- * Specifications at www.trustedcomputinggroup.org      
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2 of the
- * License.
- * 
- * Note, the TPM chip is not interrupt driven (only polling)
- * and can have very long timeouts (minutes!). Hence the unusual
- * calls to msleep.
- *
- */
-
-#include <linux/sched.h>
-#include <linux/poll.h>
-#include <linux/spinlock.h>
-#include "tpm.h"
-
-enum tpm_const {
-       TPM_MINOR = 224,        /* officially assigned */
-#ifndef CONFIG_XEN
-       TPM_BUFSIZE = 2048,
-#endif
-       TPM_NUM_DEVICES = 256,
-};
-
-enum tpm_duration {
-       TPM_SHORT = 0,
-       TPM_MEDIUM = 1,
-       TPM_LONG = 2,
-       TPM_UNDEFINED,
-};
-
-#define TPM_MAX_ORDINAL 243
-#define TPM_MAX_PROTECTED_ORDINAL 12
-#define TPM_PROTECTED_ORDINAL_MASK 0xFF
-
-static LIST_HEAD(tpm_chip_list);
-static DEFINE_SPINLOCK(driver_lock);
-static DECLARE_BITMAP(dev_mask, TPM_NUM_DEVICES);
-
-/*
- * Array with one entry per ordinal defining the maximum amount
- * of time the chip could take to return the result.  The ordinal
- * designation of short, medium or long is defined in a table in
- * TCG Specification TPM Main Part 2 TPM Structures Section 17. The
- * values of the SHORT, MEDIUM, and LONG durations are retrieved
- * from the chip during initialization with a call to tpm_get_timeouts.
- */
-static const u8 tpm_protected_ordinal_duration[TPM_MAX_PROTECTED_ORDINAL] = {
-       TPM_UNDEFINED,          /* 0 */
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,          /* 5 */
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_SHORT,              /* 10 */
-       TPM_SHORT,
-};
-
-static const u8 tpm_ordinal_duration[TPM_MAX_ORDINAL] = {
-       TPM_UNDEFINED,          /* 0 */
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,          /* 5 */
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_SHORT,              /* 10 */
-       TPM_SHORT,
-       TPM_MEDIUM,
-       TPM_LONG,
-       TPM_LONG,
-       TPM_MEDIUM,             /* 15 */
-       TPM_SHORT,
-       TPM_SHORT,
-       TPM_MEDIUM,
-       TPM_LONG,
-       TPM_SHORT,              /* 20 */
-       TPM_SHORT,
-       TPM_MEDIUM,
-       TPM_MEDIUM,
-       TPM_MEDIUM,
-       TPM_SHORT,              /* 25 */
-       TPM_SHORT,
-       TPM_MEDIUM,
-       TPM_SHORT,
-       TPM_SHORT,
-       TPM_MEDIUM,             /* 30 */
-       TPM_LONG,
-       TPM_MEDIUM,
-       TPM_SHORT,
-       TPM_SHORT,
-       TPM_SHORT,              /* 35 */
-       TPM_MEDIUM,
-       TPM_MEDIUM,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_MEDIUM,             /* 40 */
-       TPM_LONG,
-       TPM_MEDIUM,
-       TPM_SHORT,
-       TPM_SHORT,
-       TPM_SHORT,              /* 45 */
-       TPM_SHORT,
-       TPM_SHORT,
-       TPM_SHORT,
-       TPM_LONG,
-       TPM_MEDIUM,             /* 50 */
-       TPM_MEDIUM,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,          /* 55 */
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_MEDIUM,             /* 60 */
-       TPM_MEDIUM,
-       TPM_MEDIUM,
-       TPM_SHORT,
-       TPM_SHORT,
-       TPM_MEDIUM,             /* 65 */
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_SHORT,              /* 70 */
-       TPM_SHORT,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,          /* 75 */
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_LONG,               /* 80 */
-       TPM_UNDEFINED,
-       TPM_MEDIUM,
-       TPM_LONG,
-       TPM_SHORT,
-       TPM_UNDEFINED,          /* 85 */
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_SHORT,              /* 90 */
-       TPM_SHORT,
-       TPM_SHORT,
-       TPM_SHORT,
-       TPM_SHORT,
-       TPM_UNDEFINED,          /* 95 */
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_MEDIUM,             /* 100 */
-       TPM_SHORT,
-       TPM_SHORT,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,          /* 105 */
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_SHORT,              /* 110 */
-       TPM_SHORT,
-       TPM_SHORT,
-       TPM_SHORT,
-       TPM_SHORT,
-       TPM_SHORT,              /* 115 */
-       TPM_SHORT,
-       TPM_SHORT,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_LONG,               /* 120 */
-       TPM_LONG,
-       TPM_MEDIUM,
-       TPM_UNDEFINED,
-       TPM_SHORT,
-       TPM_SHORT,              /* 125 */
-       TPM_SHORT,
-       TPM_LONG,
-       TPM_SHORT,
-       TPM_SHORT,
-       TPM_SHORT,              /* 130 */
-       TPM_MEDIUM,
-       TPM_UNDEFINED,
-       TPM_SHORT,
-       TPM_MEDIUM,
-       TPM_UNDEFINED,          /* 135 */
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_SHORT,              /* 140 */
-       TPM_SHORT,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,          /* 145 */
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_SHORT,              /* 150 */
-       TPM_MEDIUM,
-       TPM_MEDIUM,
-       TPM_SHORT,
-       TPM_SHORT,
-       TPM_UNDEFINED,          /* 155 */
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_SHORT,              /* 160 */
-       TPM_SHORT,
-       TPM_SHORT,
-       TPM_SHORT,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,          /* 165 */
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_LONG,               /* 170 */
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,          /* 175 */
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_MEDIUM,             /* 180 */
-       TPM_SHORT,
-       TPM_MEDIUM,
-       TPM_MEDIUM,
-       TPM_MEDIUM,
-       TPM_MEDIUM,             /* 185 */
-       TPM_SHORT,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,          /* 190 */
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,          /* 195 */
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_SHORT,              /* 200 */
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_SHORT,
-       TPM_SHORT,              /* 205 */
-       TPM_SHORT,
-       TPM_SHORT,
-       TPM_SHORT,
-       TPM_SHORT,
-       TPM_MEDIUM,             /* 210 */
-       TPM_UNDEFINED,
-       TPM_MEDIUM,
-       TPM_MEDIUM,
-       TPM_MEDIUM,
-       TPM_UNDEFINED,          /* 215 */
-       TPM_MEDIUM,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_SHORT,
-       TPM_SHORT,              /* 220 */
-       TPM_SHORT,
-       TPM_SHORT,
-       TPM_SHORT,
-       TPM_SHORT,
-       TPM_UNDEFINED,          /* 225 */
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_SHORT,              /* 230 */
-       TPM_LONG,
-       TPM_MEDIUM,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,          /* 235 */
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_UNDEFINED,
-       TPM_SHORT,              /* 240 */
-       TPM_UNDEFINED,
-       TPM_MEDIUM,
-};
-
-static void user_reader_timeout(unsigned long ptr)
-{
-       struct tpm_chip *chip = (struct tpm_chip *) ptr;
-
-       schedule_work(&chip->work);
-}
-
-static void timeout_work(void *ptr)
-{
-       struct tpm_chip *chip = ptr;
-
-       down(&chip->buffer_mutex);
-       atomic_set(&chip->data_pending, 0);
-#ifndef CONFIG_XEN
-       memset(chip->data_buffer, 0, TPM_BUFSIZE);
-#else
-       memset(chip->data_buffer, 0, get_chip_buffersize(chip));
-#endif
-       up(&chip->buffer_mutex);
-}
-
-/*
- * Returns max number of jiffies to wait
- */
-unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
-                                          u32 ordinal)
-{
-       int duration_idx = TPM_UNDEFINED;
-       int duration = 0;
-
-       if (ordinal < TPM_MAX_ORDINAL)
-               duration_idx = tpm_ordinal_duration[ordinal];
-       else if ((ordinal & TPM_PROTECTED_ORDINAL_MASK) <
-                TPM_MAX_PROTECTED_ORDINAL)
-               duration_idx =
-                   tpm_protected_ordinal_duration[ordinal &
-                                                  TPM_PROTECTED_ORDINAL_MASK];
-
-       if (duration_idx != TPM_UNDEFINED)
-               duration = chip->vendor.duration[duration_idx];
-       if (duration <= 0)
-               return 2 * 60 * HZ;
-       else
-               return duration;
-}
-EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration);
-
-/*
- * Internal kernel interface to transmit TPM commands
- */
-static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
-                           size_t bufsiz)
-{
-       ssize_t rc;
-       u32 count, ordinal;
-       unsigned long stop;
-
-       count = be32_to_cpu(*((__be32 *) (buf + 2)));
-       ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
-       if (count == 0)
-               return -ENODATA;
-       if (count > bufsiz) {
-               dev_err(chip->dev,
-                       "invalid count value %x %zx \n", count, bufsiz);
-               return -E2BIG;
-       }
-
-       down(&chip->tpm_mutex);
-
-       if ((rc = chip->vendor.send(chip, (u8 *) buf, count)) < 0) {
-               dev_err(chip->dev,
-                       "tpm_transmit: tpm_send: error %zd\n", rc);
-               goto out;
-       }
-
-       if (chip->vendor.irq)
-               goto out_recv;
-
-       stop = jiffies + tpm_calc_ordinal_duration(chip, ordinal);
-       do {
-               u8 status = chip->vendor.status(chip);
-               if ((status & chip->vendor.req_complete_mask) ==
-                   chip->vendor.req_complete_val)
-                       goto out_recv;
-
-               if ((status == chip->vendor.req_canceled)) {
-                       dev_err(chip->dev, "Operation Canceled\n");
-                       rc = -ECANCELED;
-                       goto out;
-               }
-
-               msleep(TPM_TIMEOUT);    /* CHECK */
-               rmb();
-       } while (time_before(jiffies, stop));
-
-       chip->vendor.cancel(chip);
-       dev_err(chip->dev, "Operation Timed out\n");
-       rc = -ETIME;
-       goto out;
-
-out_recv:
-       rc = chip->vendor.recv(chip, (u8 *) buf, bufsiz);
-       if (rc < 0)
-               dev_err(chip->dev,
-                       "tpm_transmit: tpm_recv: error %zd\n", rc);
-out:
-       up(&chip->tpm_mutex);
-       return rc;
-}
-
-#define TPM_DIGEST_SIZE 20
-#define TPM_ERROR_SIZE 10
-#define TPM_RET_CODE_IDX 6
-#define TPM_GET_CAP_RET_SIZE_IDX 10
-#define TPM_GET_CAP_RET_UINT32_1_IDX 14
-#define TPM_GET_CAP_RET_UINT32_2_IDX 18
-#define TPM_GET_CAP_RET_UINT32_3_IDX 22
-#define TPM_GET_CAP_RET_UINT32_4_IDX 26
-#define TPM_GET_CAP_PERM_DISABLE_IDX 16
-#define TPM_GET_CAP_PERM_INACTIVE_IDX 18
-#define TPM_GET_CAP_RET_BOOL_1_IDX 14
-#define TPM_GET_CAP_TEMP_INACTIVE_IDX 16
-
-#define TPM_CAP_IDX 13
-#define TPM_CAP_SUBCAP_IDX 21
-
-enum tpm_capabilities {
-       TPM_CAP_FLAG = 4,
-       TPM_CAP_PROP = 5,
-};
-
-enum tpm_sub_capabilities {
-       TPM_CAP_PROP_PCR = 0x1,
-       TPM_CAP_PROP_MANUFACTURER = 0x3,
-       TPM_CAP_FLAG_PERM = 0x8,
-       TPM_CAP_FLAG_VOL = 0x9,
-       TPM_CAP_PROP_OWNER = 0x11,
-       TPM_CAP_PROP_TIS_TIMEOUT = 0x15,
-       TPM_CAP_PROP_TIS_DURATION = 0x20,
-};
-
-/*
- * This is a semi generic GetCapability command for use
- * with the capability type TPM_CAP_PROP or TPM_CAP_FLAG
- * and their associated sub_capabilities.
- */
-
-static const u8 tpm_cap[] = {
-       0, 193,                 /* TPM_TAG_RQU_COMMAND */
-       0, 0, 0, 22,            /* length */
-       0, 0, 0, 101,           /* TPM_ORD_GetCapability */
-       0, 0, 0, 0,             /* TPM_CAP_<TYPE> */
-       0, 0, 0, 4,             /* TPM_CAP_SUB_<TYPE> size */
-       0, 0, 1, 0              /* TPM_CAP_SUB_<TYPE> */
-};
-
-static ssize_t transmit_cmd(struct tpm_chip *chip, u8 *data, int len,
-                           char *desc)
-{
-       int err;
-
-       len = tpm_transmit(chip, data, len);
-       if (len <  0)
-               return len;
-       if (len == TPM_ERROR_SIZE) {
-               err = be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX)));
-               dev_dbg(chip->dev, "A TPM error (%d) occurred %s\n", err, desc);
-               return err;
-       }
-       return 0;
-}
-
-void tpm_gen_interrupt(struct tpm_chip *chip)
-{
-       u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
-       ssize_t rc;
-
-       memcpy(data, tpm_cap, sizeof(tpm_cap));
-       data[TPM_CAP_IDX] = TPM_CAP_PROP;
-       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
-
-       rc = transmit_cmd(chip, data, sizeof(data),
-                       "attempting to determine the timeouts");
-}
-EXPORT_SYMBOL_GPL(tpm_gen_interrupt);
-
-void tpm_get_timeouts(struct tpm_chip *chip)
-{
-       u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
-       ssize_t rc;
-       u32 timeout;
-
-       memcpy(data, tpm_cap, sizeof(tpm_cap));
-       data[TPM_CAP_IDX] = TPM_CAP_PROP;
-       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
-
-       rc = transmit_cmd(chip, data, sizeof(data),
-                       "attempting to determine the timeouts");
-       if (rc)
-               goto duration;
-
-       if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
-           != 4 * sizeof(u32))
-               goto duration;
-
-       /* Don't overwrite default if value is 0 */
-       timeout =
-           be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)));
-       if (timeout)
-               chip->vendor.timeout_a = msecs_to_jiffies(timeout);
-       timeout =
-           be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX)));
-       if (timeout)
-               chip->vendor.timeout_b = msecs_to_jiffies(timeout);
-       timeout =
-           be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX)));
-       if (timeout)
-               chip->vendor.timeout_c = msecs_to_jiffies(timeout);
-       timeout =
-           be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_4_IDX)));
-       if (timeout)
-               chip->vendor.timeout_d = msecs_to_jiffies(timeout);
-
-duration:
-       memcpy(data, tpm_cap, sizeof(tpm_cap));
-       data[TPM_CAP_IDX] = TPM_CAP_PROP;
-       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_DURATION;
-
-       rc = transmit_cmd(chip, data, sizeof(data),
-                       "attempting to determine the durations");
-       if (rc)
-               return;
-
-       if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
-           != 3 * sizeof(u32))
-               return;
-
-       chip->vendor.duration[TPM_SHORT] =
-           msecs_to_jiffies(be32_to_cpu
-                            (*((__be32 *) (data +
-                                           TPM_GET_CAP_RET_UINT32_1_IDX))));
-       chip->vendor.duration[TPM_MEDIUM] =
-           msecs_to_jiffies(be32_to_cpu
-                            (*((__be32 *) (data +
-                                           TPM_GET_CAP_RET_UINT32_2_IDX))));
-       chip->vendor.duration[TPM_LONG] =
-           msecs_to_jiffies(be32_to_cpu
-                            (*((__be32 *) (data +
-                                           TPM_GET_CAP_RET_UINT32_3_IDX))));
-}
-EXPORT_SYMBOL_GPL(tpm_get_timeouts);
-
-void tpm_continue_selftest(struct tpm_chip *chip)
-{
-       u8 data[] = {
-               0, 193,                 /* TPM_TAG_RQU_COMMAND */
-               0, 0, 0, 10,            /* length */
-               0, 0, 0, 83,            /* TPM_ORD_GetCapability */
-       };
-
-       tpm_transmit(chip, data, sizeof(data));
-}
-EXPORT_SYMBOL_GPL(tpm_continue_selftest);
-
-ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr,
-                       char *buf)
-{
-       u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)];
-       ssize_t rc;
-
-       struct tpm_chip *chip = dev_get_drvdata(dev);
-       if (chip == NULL)
-               return -ENODEV;
-
-       memcpy(data, tpm_cap, sizeof(tpm_cap));
-       data[TPM_CAP_IDX] = TPM_CAP_FLAG;
-       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
-
-       rc = transmit_cmd(chip, data, sizeof(data),
-                       "attemtping to determine the permanent state");
-       if (rc)
-               return 0;
-       return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_DISABLE_IDX]);
-}
-EXPORT_SYMBOL_GPL(tpm_show_enabled);
-
-ssize_t tpm_show_active(struct device * dev, struct device_attribute * attr,
-                       char *buf)
-{
-       u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)];
-       ssize_t rc;
-
-       struct tpm_chip *chip = dev_get_drvdata(dev);
-       if (chip == NULL)
-               return -ENODEV;
-
-       memcpy(data, tpm_cap, sizeof(tpm_cap));
-       data[TPM_CAP_IDX] = TPM_CAP_FLAG;
-       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
-
-       rc = transmit_cmd(chip, data, sizeof(data),
-                       "attemtping to determine the permanent state");
-       if (rc)
-               return 0;
-       return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_INACTIVE_IDX]);
-}
-EXPORT_SYMBOL_GPL(tpm_show_active);
-
-ssize_t tpm_show_owned(struct device * dev, struct device_attribute * attr,
-                       char *buf)
-{
-       u8 data[sizeof(tpm_cap)];
-       ssize_t rc;
-
-       struct tpm_chip *chip = dev_get_drvdata(dev);
-       if (chip == NULL)
-               return -ENODEV;
-
-       memcpy(data, tpm_cap, sizeof(tpm_cap));
-       data[TPM_CAP_IDX] = TPM_CAP_PROP;
-       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_OWNER;
-
-       rc = transmit_cmd(chip, data, sizeof(data),
-                       "attempting to determine the owner state");
-       if (rc)
-               return 0;
-       return sprintf(buf, "%d\n", data[TPM_GET_CAP_RET_BOOL_1_IDX]);
-}
-EXPORT_SYMBOL_GPL(tpm_show_owned);
-
-ssize_t tpm_show_temp_deactivated(struct device * dev,
-                               struct device_attribute * attr, char *buf)
-{
-       u8 data[sizeof(tpm_cap)];
-       ssize_t rc;
-
-       struct tpm_chip *chip = dev_get_drvdata(dev);
-       if (chip == NULL)
-               return -ENODEV;
-
-       memcpy(data, tpm_cap, sizeof(tpm_cap));
-       data[TPM_CAP_IDX] = TPM_CAP_FLAG;
-       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_VOL;
-
-       rc = transmit_cmd(chip, data, sizeof(data),
-                       "attempting to determine the temporary state");
-       if (rc)
-               return 0;
-       return sprintf(buf, "%d\n", data[TPM_GET_CAP_TEMP_INACTIVE_IDX]);
-}
-EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated);
-
-static const u8 pcrread[] = {
-       0, 193,                 /* TPM_TAG_RQU_COMMAND */
-       0, 0, 0, 14,            /* length */
-       0, 0, 0, 21,            /* TPM_ORD_PcrRead */
-       0, 0, 0, 0              /* PCR index */
-};
-
-ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
-                     char *buf)
-{
-       u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(pcrread)), 30)];
-       ssize_t rc;
-       int i, j, num_pcrs;
-       __be32 index;
-       char *str = buf;
-
-       struct tpm_chip *chip = dev_get_drvdata(dev);
-       if (chip == NULL)
-               return -ENODEV;
-
-       memcpy(data, tpm_cap, sizeof(tpm_cap));
-       data[TPM_CAP_IDX] = TPM_CAP_PROP;
-       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_PCR;
-
-       rc = transmit_cmd(chip, data, sizeof(data),
-                       "attempting to determine the number of PCRS");
-       if (rc)
-               return 0;
-
-       num_pcrs = be32_to_cpu(*((__be32 *) (data + 14)));
-       for (i = 0; i < num_pcrs; i++) {
-               memcpy(data, pcrread, sizeof(pcrread));
-               index = cpu_to_be32(i);
-               memcpy(data + 10, &index, 4);
-               rc = transmit_cmd(chip, data, sizeof(data),
-                               "attempting to read a PCR");
-               if (rc)
-                       goto out;
-               str += sprintf(str, "PCR-%02d: ", i);
-               for (j = 0; j < TPM_DIGEST_SIZE; j++)
-                       str += sprintf(str, "%02X ", *(data + 10 + j));
-               str += sprintf(str, "\n");
-       }
-out:
-       return str - buf;
-}
-EXPORT_SYMBOL_GPL(tpm_show_pcrs);
-
-#define  READ_PUBEK_RESULT_SIZE 314
-static const u8 readpubek[] = {
-       0, 193,                 /* TPM_TAG_RQU_COMMAND */
-       0, 0, 0, 30,            /* length */
-       0, 0, 0, 124,           /* TPM_ORD_ReadPubek */
-};
-
-ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
-                      char *buf)
-{
-       u8 *data;
-       ssize_t err;
-       int i, rc;
-       char *str = buf;
-
-       struct tpm_chip *chip = dev_get_drvdata(dev);
-       if (chip == NULL)
-               return -ENODEV;
-
-       data = kzalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL);
-       if (!data)
-               return -ENOMEM;
-
-       memcpy(data, readpubek, sizeof(readpubek));
-
-       err = transmit_cmd(chip, data, READ_PUBEK_RESULT_SIZE,
-                       "attempting to read the PUBEK");
-       if (err)
-               goto out;
-
-       /* 
-          ignore header 10 bytes
-          algorithm 32 bits (1 == RSA )
-          encscheme 16 bits
-          sigscheme 16 bits
-          parameters (RSA 12->bytes: keybit, #primes, expbit)  
-          keylenbytes 32 bits
-          256 byte modulus
-          ignore checksum 20 bytes
-        */
-
-       str +=
-           sprintf(str,
-                   "Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n"
-                   "Sigscheme: %02X %02X\nParameters: %02X %02X %02X %02X"
-                   " %02X %02X %02X %02X %02X %02X %02X %02X\n"
-                   "Modulus length: %d\nModulus: \n",
-                   data[10], data[11], data[12], data[13], data[14],
-                   data[15], data[16], data[17], data[22], data[23],
-                   data[24], data[25], data[26], data[27], data[28],
-                   data[29], data[30], data[31], data[32], data[33],
-                   be32_to_cpu(*((__be32 *) (data + 34))));
-
-       for (i = 0; i < 256; i++) {
-               str += sprintf(str, "%02X ", data[i + 38]);
-               if ((i + 1) % 16 == 0)
-                       str += sprintf(str, "\n");
-       }
-out:
-       rc = str - buf;
-       kfree(data);
-       return rc;
-}
-EXPORT_SYMBOL_GPL(tpm_show_pubek);
-
-#define CAP_VERSION_1_1 6
-#define CAP_VERSION_1_2 0x1A
-#define CAP_VERSION_IDX 13
-static const u8 cap_version[] = {
-       0, 193,                 /* TPM_TAG_RQU_COMMAND */
-       0, 0, 0, 18,            /* length */
-       0, 0, 0, 101,           /* TPM_ORD_GetCapability */
-       0, 0, 0, 0,
-       0, 0, 0, 0
-};
-
-ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
-                     char *buf)
-{
-       u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 
30)];
-       ssize_t rc;
-       char *str = buf;
-
-       struct tpm_chip *chip = dev_get_drvdata(dev);
-       if (chip == NULL)
-               return -ENODEV;
-
-       memcpy(data, tpm_cap, sizeof(tpm_cap));
-       data[TPM_CAP_IDX] = TPM_CAP_PROP;
-       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
-
-       rc = transmit_cmd(chip, data, sizeof(data),
-                       "attempting to determine the manufacturer");
-       if (rc)
-               return 0;
-
-       str += sprintf(str, "Manufacturer: 0x%x\n",
-                      be32_to_cpu(*((__be32 *) (data + 
TPM_GET_CAP_RET_UINT32_1_IDX))));
-
-       memcpy(data, cap_version, sizeof(cap_version));
-       data[CAP_VERSION_IDX] = CAP_VERSION_1_1;
-       rc = transmit_cmd(chip, data, sizeof(data),
-                       "attempting to determine the 1.1 version");
-       if (rc)
-               goto out;
-
-       str += sprintf(str,
-                      "TCG version: %d.%d\nFirmware version: %d.%d\n",
-                      (int) data[14], (int) data[15], (int) data[16],
-                      (int) data[17]);
-
-out:
-       return str - buf;
-}
-EXPORT_SYMBOL_GPL(tpm_show_caps);
-
-ssize_t tpm_show_caps_1_2(struct device * dev,
-                         struct device_attribute * attr, char *buf)
-{
-       u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 
30)];
-       ssize_t len;
-       char *str = buf;
-
-       struct tpm_chip *chip = dev_get_drvdata(dev);
-       if (chip == NULL)
-               return -ENODEV;
-
-       memcpy(data, tpm_cap, sizeof(tpm_cap));
-       data[TPM_CAP_IDX] = TPM_CAP_PROP;
-       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
-
-       if ((len = tpm_transmit(chip, data, sizeof(data))) <=
-           TPM_ERROR_SIZE) {
-               dev_dbg(chip->dev, "A TPM error (%d) occurred "
-                       "attempting to determine the manufacturer\n",
-                       be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
-               return 0;
-       }
-
-       str += sprintf(str, "Manufacturer: 0x%x\n",
-                      be32_to_cpu(*((__be32 *) (data + 
TPM_GET_CAP_RET_UINT32_1_IDX))));
-
-       memcpy(data, cap_version, sizeof(cap_version));
-       data[CAP_VERSION_IDX] = CAP_VERSION_1_2;
-
-       if ((len = tpm_transmit(chip, data, sizeof(data))) <=
-           TPM_ERROR_SIZE) {
-               dev_err(chip->dev, "A TPM error (%d) occurred "
-                       "attempting to determine the 1.2 version\n",
-                       be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
-               goto out;
-       }
-       str += sprintf(str,
-                      "TCG version: %d.%d\nFirmware version: %d.%d\n",
-                      (int) data[16], (int) data[17], (int) data[18],
-                      (int) data[19]);
-
-out:
-       return str - buf;
-}
-EXPORT_SYMBOL_GPL(tpm_show_caps_1_2);
-
-ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
-                       const char *buf, size_t count)
-{
-       struct tpm_chip *chip = dev_get_drvdata(dev);
-       if (chip == NULL)
-               return 0;
-
-       chip->vendor.cancel(chip);
-       return count;
-}
-EXPORT_SYMBOL_GPL(tpm_store_cancel);
-
-/*
- * Device file system interface to the TPM
- */
-int tpm_open(struct inode *inode, struct file *file)
-{
-       int rc = 0, minor = iminor(inode);
-       struct tpm_chip *chip = NULL, *pos;
-
-       spin_lock(&driver_lock);
-
-       list_for_each_entry(pos, &tpm_chip_list, list) {
-               if (pos->vendor.miscdev.minor == minor) {
-                       chip = pos;
-                       break;
-               }
-       }
-
-       if (chip == NULL) {
-               rc = -ENODEV;
-               goto err_out;
-       }
-
-       if (chip->num_opens) {
-               dev_dbg(chip->dev, "Another process owns this TPM\n");
-               rc = -EBUSY;
-               goto err_out;
-       }
-
-       chip->num_opens++;
-       get_device(chip->dev);
-
-       spin_unlock(&driver_lock);
-
-#ifndef CONFIG_XEN
-       chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
-#else
-       chip->data_buffer = kmalloc(get_chip_buffersize(chip) * sizeof(u8),
-                                   GFP_KERNEL);
-#endif
-       if (chip->data_buffer == NULL) {
-               chip->num_opens--;
-               put_device(chip->dev);
-               return -ENOMEM;
-       }
-
-       atomic_set(&chip->data_pending, 0);
-
-       file->private_data = chip;
-       return 0;
-
-err_out:
-       spin_unlock(&driver_lock);
-       return rc;
-}
-EXPORT_SYMBOL_GPL(tpm_open);
-
-int tpm_release(struct inode *inode, struct file *file)
-{
-       struct tpm_chip *chip = file->private_data;
-
-       spin_lock(&driver_lock);
-       file->private_data = NULL;
-       chip->num_opens--;
-       del_singleshot_timer_sync(&chip->user_read_timer);
-       flush_scheduled_work();
-       atomic_set(&chip->data_pending, 0);
-       put_device(chip->dev);
-       kfree(chip->data_buffer);
-       spin_unlock(&driver_lock);
-       return 0;
-}
-EXPORT_SYMBOL_GPL(tpm_release);
-
-ssize_t tpm_write(struct file *file, const char __user *buf,
-                 size_t size, loff_t *off)
-{
-       struct tpm_chip *chip = file->private_data;
-       int in_size = size, out_size;
-
-       /* cannot perform a write until the read has cleared
-          either via tpm_read or a user_read_timer timeout */
-       while (atomic_read(&chip->data_pending) != 0)
-               msleep(TPM_TIMEOUT);
-
-       down(&chip->buffer_mutex);
-
-#ifndef CONFIG_XEN
-       if (in_size > TPM_BUFSIZE)
-               in_size = TPM_BUFSIZE;
-#else
-       if (in_size > get_chip_buffersize(chip))
-               in_size = get_chip_buffersize(chip);
-#endif
-
-       if (copy_from_user
-           (chip->data_buffer, (void __user *) buf, in_size)) {
-               up(&chip->buffer_mutex);
-               return -EFAULT;
-       }
-
-       /* atomic tpm command send and result receive */
-#ifndef CONFIG_XEN
-       out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE);
-#else
-       out_size = tpm_transmit(chip, chip->data_buffer,
-                               get_chip_buffersize(chip));
-#endif
-
-       atomic_set(&chip->data_pending, out_size);
-#ifdef CONFIG_XEN
-       atomic_set(&chip->data_position, 0);
-#endif
-       up(&chip->buffer_mutex);
-
-       /* Set a timeout by which the reader must come claim the result */
-       mod_timer(&chip->user_read_timer, jiffies + (60 * HZ));
-
-       return in_size;
-}
-EXPORT_SYMBOL_GPL(tpm_write);
-
-ssize_t tpm_read(struct file *file, char __user *buf,
-                size_t size, loff_t *off)
-{
-       struct tpm_chip *chip = file->private_data;
-       int ret_size;
-#ifdef CONFIG_XEN
-       int pos, pending = 0;
-#endif
-
-#ifndef CONFIG_XEN
-       del_singleshot_timer_sync(&chip->user_read_timer);
-       flush_scheduled_work();
-#endif
-       ret_size = atomic_read(&chip->data_pending);
-#ifndef CONFIG_XEN
-       atomic_set(&chip->data_pending, 0);
-#endif
-       if (ret_size > 0) {     /* relay data */
-               if (size < ret_size)
-                       ret_size = size;
-
-#ifdef CONFIG_XEN
-               pos = atomic_read(&chip->data_position);
-#endif
-               down(&chip->buffer_mutex);
-#ifndef CONFIG_XEN
-               if (copy_to_user(buf, chip->data_buffer, ret_size))
-#else
-               if (copy_to_user(buf, &chip->data_buffer[pos], ret_size)) {
-#endif
-                       ret_size = -EFAULT;
-#ifdef CONFIG_XEN
-               } else {
-                       pending = atomic_read(&chip->data_pending) - ret_size;
-                       if ( pending ) {
-                               atomic_set(&chip->data_pending, pending);
-                               atomic_set(&chip->data_position,
-                                          pos+ret_size);
-                       }
-               }
-#endif
-               up(&chip->buffer_mutex);
-       }
-
-#ifdef CONFIG_XEN
-       if ( ret_size <= 0 || pending == 0 ) {
-               atomic_set(&chip->data_pending, 0);
-               del_singleshot_timer_sync(&chip->user_read_timer);
-               flush_scheduled_work();
-       }
-#endif
-       return ret_size;
-}
-EXPORT_SYMBOL_GPL(tpm_read);
-
-void tpm_remove_hardware(struct device *dev)
-{
-       struct tpm_chip *chip = dev_get_drvdata(dev);
-
-       if (chip == NULL) {
-               dev_err(dev, "No device data found\n");
-               return;
-       }
-
-       spin_lock(&driver_lock);
-
-       list_del(&chip->list);
-
-       spin_unlock(&driver_lock);
-
-       dev_set_drvdata(dev, NULL);
-       misc_deregister(&chip->vendor.miscdev);
-       kfree(chip->vendor.miscdev.name);
-
-       sysfs_remove_group(&dev->kobj, chip->vendor.attr_group);
-       tpm_bios_log_teardown(chip->bios_dir);
-
-       clear_bit(chip->dev_num, dev_mask);
-
-       kfree(chip);
-
-       put_device(dev);
-}
-EXPORT_SYMBOL_GPL(tpm_remove_hardware);
-
-static u8 savestate[] = {
-       0, 193,                 /* TPM_TAG_RQU_COMMAND */
-       0, 0, 0, 10,            /* blob length (in bytes) */
-       0, 0, 0, 152            /* TPM_ORD_SaveState */
-};
-
-/*
- * We are about to suspend. Save the TPM state
- * so that it can be restored.
- */
-int tpm_pm_suspend(struct device *dev, pm_message_t pm_state)
-{
-       struct tpm_chip *chip = dev_get_drvdata(dev);
-       if (chip == NULL)
-               return -ENODEV;
-
-       tpm_transmit(chip, savestate, sizeof(savestate));
-       return 0;
-}
-EXPORT_SYMBOL_GPL(tpm_pm_suspend);
-
-/*
- * Resume from a power safe. The BIOS already restored
- * the TPM state.
- */
-int tpm_pm_resume(struct device *dev)
-{
-       struct tpm_chip *chip = dev_get_drvdata(dev);
-
-       if (chip == NULL)
-               return -ENODEV;
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(tpm_pm_resume);
-
-/*
- * Called from tpm_<specific>.c probe function only for devices 
- * the driver has determined it should claim.  Prior to calling
- * this function the specific probe function has called pci_enable_device
- * upon errant exit from this function specific probe function should call
- * pci_disable_device
- */
-struct tpm_chip *tpm_register_hardware(struct device *dev, const struct 
tpm_vendor_specific
-                                      *entry)
-{
-#define DEVNAME_SIZE 7
-
-       char *devname;
-       struct tpm_chip *chip;
-
-       /* Driver specific per-device data */
-       chip = kzalloc(sizeof(*chip), GFP_KERNEL);
-       if (chip == NULL)
-               return NULL;
-
-       init_MUTEX(&chip->buffer_mutex);
-       init_MUTEX(&chip->tpm_mutex);
-       INIT_LIST_HEAD(&chip->list);
-
-       INIT_WORK(&chip->work, timeout_work, chip);
-
-       init_timer(&chip->user_read_timer);
-       chip->user_read_timer.function = user_reader_timeout;
-       chip->user_read_timer.data = (unsigned long) chip;
-
-       memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific));
-
-       chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES);
-
-       if (chip->dev_num >= TPM_NUM_DEVICES) {
-               dev_err(dev, "No available tpm device numbers\n");
-               kfree(chip);
-               return NULL;
-       } else if (chip->dev_num == 0)
-               chip->vendor.miscdev.minor = TPM_MINOR;
-       else
-               chip->vendor.miscdev.minor = MISC_DYNAMIC_MINOR;
-
-       set_bit(chip->dev_num, dev_mask);
-
-       devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
-       scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);
-       chip->vendor.miscdev.name = devname;
-
-       chip->vendor.miscdev.dev = dev;
-       chip->dev = get_device(dev);
-
-       if (misc_register(&chip->vendor.miscdev)) {
-               dev_err(chip->dev,
-                       "unable to misc_register %s, minor %d\n",
-                       chip->vendor.miscdev.name,
-                       chip->vendor.miscdev.minor);
-               put_device(dev);
-               clear_bit(chip->dev_num, dev_mask);
-               kfree(chip);
-               kfree(devname);
-               return NULL;
-       }
-
-       spin_lock(&driver_lock);
-
-       dev_set_drvdata(dev, chip);
-
-       list_add(&chip->list, &tpm_chip_list);
-
-       spin_unlock(&driver_lock);
-
-       sysfs_create_group(&dev->kobj, chip->vendor.attr_group);
-
-       chip->bios_dir = tpm_bios_log_setup(devname);
-
-       return chip;
-}
-EXPORT_SYMBOL_GPL(tpm_register_hardware);
-
-MODULE_AUTHOR("Leendert van Doorn (leendert@xxxxxxxxxxxxxx)");
-MODULE_DESCRIPTION("TPM Driver");
-MODULE_VERSION("2.0");
-MODULE_LICENSE("GPL");
diff -r 04c23c1ef888 -r d907467f08cd linux-2.6-xen-sparse/drivers/char/tpm/tpm.h
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm.h       Sun Feb 18 16:13:13 
2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm.h       Tue Feb 20 12:58:22 
2007 -0700
@@ -25,13 +25,6 @@
 #include <linux/miscdevice.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
-
-#ifdef CONFIG_XEN
-enum tpm_bufsize {
-       TPM_MIN_BUFFERSIZE = 2048,
-       TPM_MAX_BUFFERSIZE = 64 * 1024,
-};
-#endif
 
 enum tpm_timeout {
        TPM_TIMEOUT = 5,        /* msecs */
@@ -68,9 +61,6 @@ struct tpm_vendor_specific {
        const u8 req_complete_mask;
        const u8 req_complete_val;
        const u8 req_canceled;
-#ifdef CONFIG_XEN
-       u32 buffersize;
-#endif
        void __iomem *iobase;           /* ioremapped address */
        unsigned long base;             /* TPM base address */
 
@@ -104,9 +94,6 @@ struct tpm_chip {
        /* Data passed to and from the tpm via the read/write calls */
        u8 *data_buffer;
        atomic_t data_pending;
-#ifdef CONFIG_XEN
-       atomic_t data_position;
-#endif
        struct semaphore buffer_mutex;
 
        struct timer_list user_read_timer;      /* user needs to claim result */
@@ -138,17 +125,6 @@ static inline void tpm_write_index(int b
 }
 
 #ifdef CONFIG_XEN
-static inline u32 get_chip_buffersize(struct tpm_chip *chip)
-{
-       u32 size = chip->vendor.buffersize;
-       if (size > TPM_MAX_BUFFERSIZE) {
-               return TPM_MAX_BUFFERSIZE;
-       } else if (size < TPM_MIN_BUFFERSIZE) {
-               return TPM_MIN_BUFFERSIZE;
-       }
-       return size;
-}
-
 static inline void *chip_get_private(const struct tpm_chip *chip)
 {
        return chip->priv;
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c  Sun Feb 18 16:13:13 
2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c  Tue Feb 20 12:58:22 
2007 -0700
@@ -519,9 +519,6 @@ struct tpm_chip *init_vtpm(struct device
        vtpms->tpmvd = tvd;
        vtpms->tpm_private = tp;
 
-       if (tvd)
-               tpm_vtpm.buffersize = tvd->max_tx_size;
-
        chip = tpm_register_hardware(dev, &tpm_vtpm);
        if (!chip) {
                rc = -ENODEV;
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
--- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Sun Feb 18 
16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Tue Feb 20 
12:58:22 2007 -0700
@@ -60,7 +60,7 @@ static struct proc_dir_entry *balloon_pd
 static struct proc_dir_entry *balloon_pde;
 #endif
 
-static DECLARE_MUTEX(balloon_mutex);
+static DEFINE_MUTEX(balloon_mutex);
 
 /*
  * Protects atomic reservation decrease/increase against concurrent increases.
@@ -321,7 +321,7 @@ static void balloon_process(void *unused
        int need_sleep = 0;
        long credit;
 
-       down(&balloon_mutex);
+       mutex_lock(&balloon_mutex);
 
        do {
                credit = current_target() - bs.current_pages;
@@ -340,7 +340,7 @@ static void balloon_process(void *unused
        if (current_target() != bs.current_pages)
                mod_timer(&balloon_timer, jiffies + HZ);
 
-       up(&balloon_mutex);
+       mutex_unlock(&balloon_mutex);
 }
 
 /* Resets the Xen limit, sets new target, and kicks off processing. */
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c      Sun Feb 18 
16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c      Tue Feb 20 
12:58:22 2007 -0700
@@ -58,15 +58,12 @@ static int map_frontend_page(blkif_t *bl
 static int map_frontend_page(blkif_t *blkif, unsigned long shared_page)
 {
        struct gnttab_map_grant_ref op;
-       int ret;
 
        gnttab_set_map_op(&op, (unsigned long)blkif->blk_ring_area->addr,
                          GNTMAP_host_map, shared_page, blkif->domid);
 
-       lock_vm_area(blkif->blk_ring_area);
-       ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
-       unlock_vm_area(blkif->blk_ring_area);
-       BUG_ON(ret);
+       if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
+               BUG();
 
        if (op.status) {
                DPRINTK(" Grant table operation failure !\n");
@@ -82,15 +79,12 @@ static void unmap_frontend_page(blkif_t 
 static void unmap_frontend_page(blkif_t *blkif)
 {
        struct gnttab_unmap_grant_ref op;
-       int ret;
 
        gnttab_set_unmap_op(&op, (unsigned long)blkif->blk_ring_area->addr,
                            GNTMAP_host_map, blkif->shmem_handle);
 
-       lock_vm_area(blkif->blk_ring_area);
-       ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
-       unlock_vm_area(blkif->blk_ring_area);
-       BUG_ON(ret);
+       if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
+               BUG();
 }
 
 int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/drivers/xen/blktap/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c       Sun Feb 18 
16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c       Tue Feb 20 
12:58:22 2007 -0700
@@ -58,15 +58,12 @@ static int map_frontend_page(blkif_t *bl
 static int map_frontend_page(blkif_t *blkif, unsigned long shared_page)
 {
        struct gnttab_map_grant_ref op;
-       int ret;
 
        gnttab_set_map_op(&op, (unsigned long)blkif->blk_ring_area->addr,
                          GNTMAP_host_map, shared_page, blkif->domid);
 
-       lock_vm_area(blkif->blk_ring_area);
-       ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
-       unlock_vm_area(blkif->blk_ring_area);
-       BUG_ON(ret);
+       if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
+               BUG();
 
        if (op.status) {
                DPRINTK(" Grant table operation failure !\n");
@@ -82,15 +79,12 @@ static void unmap_frontend_page(blkif_t 
 static void unmap_frontend_page(blkif_t *blkif)
 {
        struct gnttab_unmap_grant_ref op;
-       int ret;
 
        gnttab_set_unmap_op(&op, (unsigned long)blkif->blk_ring_area->addr,
                            GNTMAP_host_map, blkif->shmem_handle);
 
-       lock_vm_area(blkif->blk_ring_area);
-       ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
-       unlock_vm_area(blkif->blk_ring_area);
-       BUG_ON(ret);
+       if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
+               BUG();
 }
 
 int tap_blkif_map(blkif_t *blkif, unsigned long shared_page, 
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/drivers/xen/core/gnttab.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c    Sun Feb 18 16:13:13 
2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c    Tue Feb 20 12:58:22 
2007 -0700
@@ -3,7 +3,7 @@
  *
  * Granting foreign access to our memory reservation.
  *
- * Copyright (c) 2005, Christopher Clark
+ * Copyright (c) 2005-2006, Christopher Clark
  * Copyright (c) 2004-2005, K A Fraser
  *
  * This program is free software; you can redistribute it and/or
@@ -35,7 +35,6 @@
 #include <linux/module.h>
 #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>
@@ -43,6 +42,7 @@
 #include <asm/synch_bitops.h>
 #include <asm/io.h>
 #include <xen/interface/memory.h>
+#include <xen/driver_util.h>
 
 #ifdef HAVE_XEN_PLATFORM_COMPAT_H
 #include <xen/platform-compat.h>
@@ -50,37 +50,51 @@
 
 /* External tools reserve first few grant table entries. */
 #define NR_RESERVED_ENTRIES 8
-
-#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];
+#define GNTTAB_LIST_END 0xffffffff
+#define GREFS_PER_GRANT_FRAME (PAGE_SIZE / sizeof(grant_entry_t))
+
+static grant_ref_t **gnttab_list;
+static unsigned int nr_grant_frames;
+static unsigned int boot_max_nr_grant_frames;
 static int gnttab_free_count;
 static grant_ref_t gnttab_free_head;
 static DEFINE_SPINLOCK(gnttab_list_lock);
 
 static struct grant_entry *shared;
+#ifndef CONFIG_XEN
+static unsigned long resume_frames;
+#endif
 
 static struct gnttab_free_callback *gnttab_free_callback_list;
 
+static int gnttab_expand(unsigned int req_entries);
+
+#define RPP (PAGE_SIZE / sizeof(grant_ref_t))
+#define gnttab_entry(entry) (gnttab_list[(entry) / RPP][(entry) % RPP])
+
 static int get_free_entries(int count)
 {
        unsigned long flags;
-       int ref;
+       int ref, rc;
        grant_ref_t head;
+
        spin_lock_irqsave(&gnttab_list_lock, flags);
-       if (gnttab_free_count < count) {
+
+       if ((gnttab_free_count < count) &&
+           ((rc = gnttab_expand(count - gnttab_free_count)) < 0)) {
                spin_unlock_irqrestore(&gnttab_list_lock, flags);
-               return -1;
-       }
+               return rc;
+       }
+
        ref = head = gnttab_free_head;
        gnttab_free_count -= count;
        while (count-- > 1)
-               head = gnttab_list[head];
-       gnttab_free_head = gnttab_list[head];
-       gnttab_list[head] = GNTTAB_LIST_END;
+               head = gnttab_entry(head);
+       gnttab_free_head = gnttab_entry(head);
+       gnttab_entry(head) = GNTTAB_LIST_END;
+
        spin_unlock_irqrestore(&gnttab_list_lock, flags);
+
        return ref;
 }
 
@@ -116,7 +130,7 @@ static void put_free_entry(grant_ref_t r
 {
        unsigned long flags;
        spin_lock_irqsave(&gnttab_list_lock, flags);
-       gnttab_list[ref] = gnttab_free_head;
+       gnttab_entry(ref) = gnttab_free_head;
        gnttab_free_head = ref;
        gnttab_free_count++;
        check_free_callbacks();
@@ -132,7 +146,7 @@ int gnttab_grant_foreign_access(domid_t 
 {
        int ref;
 
-       if (unlikely((ref = get_free_entry()) == -1))
+       if (unlikely((ref = get_free_entry()) < 0))
                return -ENOSPC;
 
        shared[ref].frame = frame;
@@ -202,7 +216,7 @@ int gnttab_grant_foreign_transfer(domid_
 {
        int ref;
 
-       if (unlikely((ref = get_free_entry()) == -1))
+       if (unlikely((ref = get_free_entry()) < 0))
                return -ENOSPC;
        gnttab_grant_foreign_transfer_ref(ref, domid, pfn);
 
@@ -273,11 +287,11 @@ void gnttab_free_grant_references(grant_
                return;
        spin_lock_irqsave(&gnttab_list_lock, flags);
        ref = head;
-       while (gnttab_list[ref] != GNTTAB_LIST_END) {
-               ref = gnttab_list[ref];
+       while (gnttab_entry(ref) != GNTTAB_LIST_END) {
+               ref = gnttab_entry(ref);
                count++;
        }
-       gnttab_list[ref] = gnttab_free_head;
+       gnttab_entry(ref) = gnttab_free_head;
        gnttab_free_head = head;
        gnttab_free_count += count;
        check_free_callbacks();
@@ -289,7 +303,7 @@ int gnttab_alloc_grant_references(u16 co
 {
        int h = get_free_entries(count);
 
-       if (h == -1)
+       if (h < 0)
                return -ENOSPC;
 
        *head = h;
@@ -309,7 +323,7 @@ int gnttab_claim_grant_reference(grant_r
        grant_ref_t g = *private_head;
        if (unlikely(g == GNTTAB_LIST_END))
                return -ENOSPC;
-       *private_head = gnttab_list[g];
+       *private_head = gnttab_entry(g);
        return g;
 }
 EXPORT_SYMBOL_GPL(gnttab_claim_grant_reference);
@@ -317,7 +331,7 @@ void gnttab_release_grant_reference(gran
 void gnttab_release_grant_reference(grant_ref_t *private_head,
                                    grant_ref_t release)
 {
-       gnttab_list[release] = *private_head;
+       gnttab_entry(release) = *private_head;
        *private_head = release;
 }
 EXPORT_SYMBOL_GPL(gnttab_release_grant_reference);
@@ -356,6 +370,64 @@ void gnttab_cancel_free_callback(struct 
 }
 EXPORT_SYMBOL_GPL(gnttab_cancel_free_callback);
 
+static int grow_gnttab_list(unsigned int more_frames)
+{
+       unsigned int new_nr_grant_frames, extra_entries, i;
+
+       new_nr_grant_frames = nr_grant_frames + more_frames;
+       extra_entries       = more_frames * GREFS_PER_GRANT_FRAME;
+
+       for (i = nr_grant_frames; i < new_nr_grant_frames; i++)
+       {
+               gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_ATOMIC);
+               if (!gnttab_list[i])
+                       goto grow_nomem;
+       }
+
+
+       for (i = GREFS_PER_GRANT_FRAME * nr_grant_frames;
+            i < GREFS_PER_GRANT_FRAME * new_nr_grant_frames - 1; i++)
+               gnttab_entry(i) = i + 1;
+
+       gnttab_entry(i) = gnttab_free_head;
+       gnttab_free_head = GREFS_PER_GRANT_FRAME * nr_grant_frames;
+       gnttab_free_count += extra_entries;
+
+       nr_grant_frames = new_nr_grant_frames;
+
+       check_free_callbacks();
+
+       return 0;
+       
+grow_nomem:
+       for ( ; i >= nr_grant_frames; i--)
+               free_page((unsigned long) gnttab_list[i]);
+       return -ENOMEM;
+}
+
+static unsigned int __max_nr_grant_frames(void)
+{
+       struct gnttab_query_size query;
+       int rc;
+
+       query.dom = DOMID_SELF;
+
+       rc = HYPERVISOR_grant_table_op(GNTTABOP_query_size, &query, 1);
+       if ((rc < 0) || (query.status != GNTST_okay))
+               return 4; /* Legacy max supported number of frames */
+
+       return query.max_nr_frames;
+}
+
+static inline unsigned int max_nr_grant_frames(void)
+{
+       unsigned int xen_max = __max_nr_grant_frames();
+
+       if (xen_max > boot_max_nr_grant_frames)
+               return boot_max_nr_grant_frames;
+       return xen_max;
+}
+
 #ifdef CONFIG_XEN
 
 #ifndef __ia64__
@@ -378,49 +450,62 @@ static int unmap_pte_fn(pte_t *pte, stru
 }
 #endif
 
-int gnttab_resume(void)
+static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
 {
        struct gnttab_setup_table setup;
-       unsigned long frames[NR_GRANT_FRAMES];
+       unsigned long *frames;
+       unsigned int nr_gframes = end_idx + 1;
        int rc;
-#ifndef __ia64__
-       void *pframes = frames;
-       struct vm_struct *area;
-#endif
+
+       frames = kmalloc(nr_gframes * sizeof(unsigned long), GFP_ATOMIC);
+       if (!frames)
+               return -ENOMEM;
 
        setup.dom        = DOMID_SELF;
-       setup.nr_frames  = NR_GRANT_FRAMES;
+       setup.nr_frames  = nr_gframes;
        set_xen_guest_handle(setup.frame_list, frames);
 
        rc = HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
-       if (rc == -ENOSYS)
+       if (rc == -ENOSYS) {
+               kfree(frames);
                return -ENOSYS;
+       }
 
        BUG_ON(rc || setup.status);
 
 #ifndef __ia64__
        if (shared == NULL) {
-               area = get_vm_area(PAGE_SIZE * NR_GRANT_FRAMES, VM_IOREMAP);
+               struct vm_struct *area;
+               area = alloc_vm_area(PAGE_SIZE * max_nr_grant_frames());
                BUG_ON(area == NULL);
                shared = area->addr;
        }
        rc = apply_to_page_range(&init_mm, (unsigned long)shared,
-                                PAGE_SIZE * NR_GRANT_FRAMES,
-                                map_pte_fn, &pframes);
+                                PAGE_SIZE * nr_gframes,
+                                map_pte_fn, &frames);
        BUG_ON(rc);
+        frames -= nr_gframes; /* adjust after map_pte_fn() */
 #else
        shared = __va(frames[0] << PAGE_SHIFT);
-       printk("grant table at %p\n", shared);
 #endif
 
-       return 0;
+       kfree(frames);
+
+       return 0;
+}
+
+int gnttab_resume(void)
+{
+       if (max_nr_grant_frames() < nr_grant_frames)
+               return -ENOSYS;
+       return gnttab_map(0, nr_grant_frames - 1);
 }
 
 int gnttab_suspend(void)
 {
 #ifndef __ia64__
        apply_to_page_range(&init_mm, (unsigned long)shared,
-                           PAGE_SIZE * NR_GRANT_FRAMES,
+                           PAGE_SIZE * nr_grant_frames,
                            unmap_pte_fn, NULL);
 #endif
        return 0;
@@ -430,24 +515,39 @@ int gnttab_suspend(void)
 
 #include <platform-pci.h>
 
-int gnttab_resume(void)
-{
-       unsigned long frames;
+static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
+{
        struct xen_add_to_physmap xatp;
        unsigned int i;
 
-       frames = alloc_xen_mmio(PAGE_SIZE * NR_GRANT_FRAMES);
-
-       for (i = 0; i < NR_GRANT_FRAMES; i++) {
+       /* Loop backwards, so that the first hypercall has the largest index,
+        * ensuring that the table will grow only once.
+        */
+       for (i = end_idx; i >= start_idx; i--) {
                xatp.domid = DOMID_SELF;
                xatp.idx = i;
                xatp.space = XENMAPSPACE_grant_table;
-               xatp.gpfn = (frames >> PAGE_SHIFT) + i;
+               xatp.gpfn = (resume_frames >> PAGE_SHIFT) + i;
                if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
                        BUG();
        }
-
-       shared = ioremap(frames, PAGE_SIZE * NR_GRANT_FRAMES);
+}
+
+int gnttab_resume(void)
+{
+       struct xen_add_to_physmap xatp;
+       unsigned int i, max_nr_gframes, nr_gframes;
+
+       nr_gframes = nr_grant_frames;
+       max_nr_gframes = max_nr_grant_frames();
+       if (max_nr_gframes < nr_gframes)
+               return -ENOSYS;
+
+       resume_frames = alloc_xen_mmio(PAGE_SIZE * max_nr_gframes);
+
+       gnttab_map(0, nr_gframes - 1);
+
+       shared = ioremap(resume_frames, PAGE_SIZE * max_nr_gframes);
        if (shared == NULL) {
                printk("error to ioremap gnttab share frames\n");
                return -1;
@@ -459,28 +559,79 @@ int gnttab_suspend(void)
 int gnttab_suspend(void)
 {
        iounmap(shared);
+       resume_frames = 0;
        return 0;
 }
 
 #endif /* !CONFIG_XEN */
 
+static int gnttab_expand(unsigned int req_entries)
+{
+       int rc;
+       unsigned int cur, extra;
+
+       cur = nr_grant_frames;
+       extra = ((req_entries + (GREFS_PER_GRANT_FRAME-1)) /
+                GREFS_PER_GRANT_FRAME);
+       if (cur + extra > max_nr_grant_frames())
+               return -ENOSPC;
+
+       if ((rc = gnttab_map(cur, cur + extra - 1)) == 0)
+               rc = grow_gnttab_list(extra);
+
+       return rc;
+}
+
 int __devinit gnttab_init(void)
 {
        int i;
+       unsigned int max_nr_glist_frames;
+       unsigned int nr_init_grefs;
 
        if (!is_running_on_xen())
                return -ENODEV;
 
+       nr_grant_frames = 1;
+       boot_max_nr_grant_frames = __max_nr_grant_frames();
+
+       /* Determine the maximum number of frames required for the
+        * grant reference free list on the current hypervisor.
+        */
+       max_nr_glist_frames = (boot_max_nr_grant_frames *
+                              GREFS_PER_GRANT_FRAME /
+                              (PAGE_SIZE / sizeof(grant_ref_t)));
+
+       gnttab_list = kmalloc(max_nr_glist_frames * sizeof(grant_ref_t *),
+                             GFP_KERNEL);
+       if (gnttab_list == NULL)
+               return -ENOMEM;
+
+       for (i = 0; i < nr_grant_frames; i++) {
+               gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_KERNEL);
+               if (gnttab_list[i] == NULL)
+                       goto ini_nomem;
+       }
+
        if (gnttab_resume() < 0)
                return -ENODEV;
 
-       for (i = NR_RESERVED_ENTRIES; i < NR_GRANT_ENTRIES; i++)
-               gnttab_list[i] = i + 1;
-       gnttab_free_count = NR_GRANT_ENTRIES - NR_RESERVED_ENTRIES;
+       nr_init_grefs = nr_grant_frames * GREFS_PER_GRANT_FRAME;
+
+       for (i = NR_RESERVED_ENTRIES; i < nr_init_grefs - 1; i++)
+               gnttab_entry(i) = i + 1;
+
+       gnttab_entry(nr_init_grefs - 1) = GNTTAB_LIST_END;
+       gnttab_free_count = nr_init_grefs - NR_RESERVED_ENTRIES;
        gnttab_free_head  = NR_RESERVED_ENTRIES;
 
        printk("Grant table initialized\n");
        return 0;
+
+ ini_nomem:
+       for (i--; i >= 0; i--)
+               free_page((unsigned long)gnttab_list[i]);
+       kfree(gnttab_list);
+       return -ENOMEM;
 }
 
 #ifdef CONFIG_XEN
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/drivers/xen/core/smpboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c   Sun Feb 18 16:13:13 
2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c   Tue Feb 20 12:58:22 
2007 -0700
@@ -349,8 +349,7 @@ void __init smp_prepare_cpus(unsigned in
 
 void __devinit smp_prepare_boot_cpu(void)
 {
-       cpu_present_map  = cpumask_of_cpu(0);
-       cpu_online_map   = cpumask_of_cpu(0);
+       prefill_possible_map();
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Sun Feb 18 
16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Tue Feb 20 
12:58:22 2007 -0700
@@ -194,15 +194,12 @@ static int map_frontend_pages(
        netif_t *netif, grant_ref_t tx_ring_ref, grant_ref_t rx_ring_ref)
 {
        struct gnttab_map_grant_ref op;
-       int ret;
 
        gnttab_set_map_op(&op, (unsigned long)netif->tx_comms_area->addr,
                          GNTMAP_host_map, tx_ring_ref, netif->domid);
     
-       lock_vm_area(netif->tx_comms_area);
-       ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
-       unlock_vm_area(netif->tx_comms_area);
-       BUG_ON(ret);
+       if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
+               BUG();
 
        if (op.status) { 
                DPRINTK(" Gnttab failure mapping tx_ring_ref!\n");
@@ -215,10 +212,8 @@ static int map_frontend_pages(
        gnttab_set_map_op(&op, (unsigned long)netif->rx_comms_area->addr,
                          GNTMAP_host_map, rx_ring_ref, netif->domid);
 
-       lock_vm_area(netif->rx_comms_area);
-       ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
-       unlock_vm_area(netif->rx_comms_area);
-       BUG_ON(ret);
+       if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
+               BUG();
 
        if (op.status) {
                DPRINTK(" Gnttab failure mapping rx_ring_ref!\n");
@@ -234,23 +229,18 @@ static void unmap_frontend_pages(netif_t
 static void unmap_frontend_pages(netif_t *netif)
 {
        struct gnttab_unmap_grant_ref op;
-       int ret;
 
        gnttab_set_unmap_op(&op, (unsigned long)netif->tx_comms_area->addr,
                            GNTMAP_host_map, netif->tx_shmem_handle);
 
-       lock_vm_area(netif->tx_comms_area);
-       ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
-       unlock_vm_area(netif->tx_comms_area);
-       BUG_ON(ret);
+       if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
+               BUG();
 
        gnttab_set_unmap_op(&op, (unsigned long)netif->rx_comms_area->addr,
                            GNTMAP_host_map, netif->rx_shmem_handle);
 
-       lock_vm_area(netif->rx_comms_area);
-       ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
-       unlock_vm_area(netif->rx_comms_area);
-       BUG_ON(ret);
+       if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
+               BUG();
 }
 
 int netif_map(netif_t *netif, unsigned long tx_ring_ref,
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c      Sun Feb 18 
16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c      Tue Feb 20 
12:58:22 2007 -0700
@@ -79,16 +79,13 @@ tpmif_t *tpmif_find(domid_t domid, struc
 
 static int map_frontend_page(tpmif_t *tpmif, unsigned long shared_page)
 {
-       int ret;
        struct gnttab_map_grant_ref op;
 
        gnttab_set_map_op(&op, (unsigned long)tpmif->tx_area->addr,
                          GNTMAP_host_map, shared_page, tpmif->domid);
 
-       lock_vm_area(tpmif->tx_area);
-       ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
-       unlock_vm_area(tpmif->tx_area);
-       BUG_ON(ret);
+       if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
+               BUG();
 
        if (op.status) {
                DPRINTK(" Grant table operation failure !\n");
@@ -104,15 +101,12 @@ static void unmap_frontend_page(tpmif_t 
 static void unmap_frontend_page(tpmif_t *tpmif)
 {
        struct gnttab_unmap_grant_ref op;
-       int ret;
 
        gnttab_set_unmap_op(&op, (unsigned long)tpmif->tx_area->addr,
                            GNTMAP_host_map, tpmif->shmem_handle);
 
-       lock_vm_area(tpmif->tx_area);
-       ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
-       unlock_vm_area(tpmif->tx_area);
-       BUG_ON(ret);
+       if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
+               BUG();
 }
 
 int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
diff -r 04c23c1ef888 -r d907467f08cd linux-2.6-xen-sparse/drivers/xen/util.c
--- a/linux-2.6-xen-sparse/drivers/xen/util.c   Sun Feb 18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/util.c   Tue Feb 20 12:58:22 2007 -0700
@@ -30,6 +30,11 @@ struct vm_struct *alloc_vm_area(unsigned
                return NULL;
        }
 
+       /* Map page directories into every address space. */
+#ifdef CONFIG_X86
+       vmalloc_sync_all();
+#endif
+
        return area;
 }
 EXPORT_SYMBOL_GPL(alloc_vm_area);
@@ -42,29 +47,3 @@ void free_vm_area(struct vm_struct *area
        kfree(area);
 }
 EXPORT_SYMBOL_GPL(free_vm_area);
-
-void lock_vm_area(struct vm_struct *area)
-{
-       unsigned long i;
-       char c;
-
-       /*
-        * Prevent context switch to a lazy mm that doesn't have this area
-        * mapped into its page tables.
-        */
-       preempt_disable();
-
-       /*
-        * Ensure that the page tables are mapped into the current mm. The
-        * page-fault path will copy the page directory pointers from init_mm.
-        */
-       for (i = 0; i < area->size; i += PAGE_SIZE)
-               (void)__get_user(c, (char __user *)area->addr + i);
-}
-EXPORT_SYMBOL_GPL(lock_vm_area);
-
-void unlock_vm_area(struct vm_struct *area)
-{
-       preempt_enable();
-}
-EXPORT_SYMBOL_GPL(unlock_vm_area);
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_backend_client.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_backend_client.c   Sun Feb 
18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_backend_client.c   Tue Feb 
20 12:58:22 2007 -0700
@@ -48,9 +48,8 @@ struct vm_struct *xenbus_map_ring_valloc
        gnttab_set_map_op(&op, (unsigned long)area->addr, GNTMAP_host_map,
                          gnt_ref, dev->otherend_id);
        
-       lock_vm_area(area);
-       BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1));
-       unlock_vm_area(area);
+       if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
+               BUG();
 
        if (op.status != GNTST_okay) {
                free_vm_area(area);
@@ -76,7 +75,8 @@ int xenbus_map_ring(struct xenbus_device
        
        gnttab_set_map_op(&op, (unsigned long)vaddr, GNTMAP_host_map,
                          gnt_ref, dev->otherend_id);
-       BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1));
+       if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
+               BUG();
 
        if (op.status != GNTST_okay) {
                xenbus_dev_fatal(dev, op.status,
@@ -98,9 +98,8 @@ int xenbus_unmap_ring_vfree(struct xenbu
        gnttab_set_unmap_op(&op, (unsigned long)area->addr, GNTMAP_host_map,
                            (grant_handle_t)area->phys_addr);
 
-       lock_vm_area(area);
-       BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
-       unlock_vm_area(area);
+       if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
+               BUG();
 
        if (op.status == GNTST_okay)
                free_vm_area(area);
@@ -121,7 +120,8 @@ int xenbus_unmap_ring(struct xenbus_devi
 
        gnttab_set_unmap_op(&op, (unsigned long)vaddr, GNTMAP_host_map,
                            handle);
-       BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
+       if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
+               BUG();
 
        if (op.status != GNTST_okay)
                xenbus_dev_error(dev, op.status,
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h   Sun Feb 
18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h   Tue Feb 
20 12:58:22 2007 -0700
@@ -56,6 +56,9 @@
 
 extern shared_info_t *HYPERVISOR_shared_info;
 
+#define vcpu_info(cpu) (HYPERVISOR_shared_info->vcpu_info + (cpu))
+#define current_vcpu_info() vcpu_info(smp_processor_id())
+
 #ifdef CONFIG_X86_32
 extern unsigned long hypervisor_virt_start;
 #endif
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/irqflags.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/irqflags.h     Sun Feb 
18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/irqflags.h     Tue Feb 
20 12:58:22 2007 -0700
@@ -12,12 +12,6 @@
 
 #ifndef __ASSEMBLY__
 
-#ifdef CONFIG_SMP
-#define __vcpu_id smp_processor_id()
-#else
-#define __vcpu_id 0
-#endif
-
 /* 
  * The use of 'barrier' in the following reflects their use as local-lock
  * operations. Reentrancy must be prevented (e.g., __cli()) /before/ following
@@ -26,8 +20,7 @@
  * includes these barriers, for example.
  */
 
-#define __raw_local_save_flags()                                       \
-       (&HYPERVISOR_shared_info->vcpu_info[__vcpu_id])->evtchn_upcall_mask;
+#define __raw_local_save_flags() (current_vcpu_info()->evtchn_upcall_mask)
 
 #define raw_local_save_flags(flags) \
                do { (flags) = __raw_local_save_flags(); } while (0)
@@ -36,7 +29,7 @@ do {                                                          
        \
 do {                                                                   \
        vcpu_info_t *_vcpu;                                             \
        barrier();                                                      \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];          \
+       _vcpu = current_vcpu_info();                                    \
        if ((_vcpu->evtchn_upcall_mask = (x)) == 0) {                   \
                barrier(); /* unmask then check (avoid races) */        \
                if (unlikely(_vcpu->evtchn_upcall_pending))             \
@@ -46,9 +39,7 @@ do {                                                          
        \
 
 #define raw_local_irq_disable()                                                
\
 do {                                                                   \
-       vcpu_info_t *_vcpu;                                             \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];          \
-       _vcpu->evtchn_upcall_mask = 1;                                  \
+       current_vcpu_info()->evtchn_upcall_mask = 1;                    \
        barrier();                                                      \
 } while (0)
 
@@ -56,7 +47,7 @@ do {                                                          
        \
 do {                                                                   \
        vcpu_info_t *_vcpu;                                             \
        barrier();                                                      \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];          \
+       _vcpu = current_vcpu_info();                                    \
        _vcpu->evtchn_upcall_mask = 0;                                  \
        barrier(); /* unmask then check (avoid races) */                \
        if (unlikely(_vcpu->evtchn_upcall_pending))                     \
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/maddr.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/maddr.h        Sun Feb 
18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/maddr.h        Tue Feb 
20 12:58:22 2007 -0700
@@ -21,6 +21,7 @@ typedef unsigned long maddr_t;
 #ifdef CONFIG_XEN
 
 extern unsigned long *phys_to_machine_mapping;
+extern unsigned long  max_mapnr;
 
 #undef machine_to_phys_mapping
 extern unsigned long *machine_to_phys_mapping;
@@ -30,20 +31,20 @@ static inline unsigned long pfn_to_mfn(u
 {
        if (xen_feature(XENFEAT_auto_translated_physmap))
                return pfn;
-       return phys_to_machine_mapping[(unsigned int)(pfn)] &
-               ~FOREIGN_FRAME_BIT;
+       BUG_ON(max_mapnr && pfn >= max_mapnr);
+       return phys_to_machine_mapping[pfn] & ~FOREIGN_FRAME_BIT;
 }
 
 static inline int phys_to_machine_mapping_valid(unsigned long pfn)
 {
        if (xen_feature(XENFEAT_auto_translated_physmap))
                return 1;
+       BUG_ON(max_mapnr && pfn >= max_mapnr);
        return (phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY);
 }
 
 static inline unsigned long mfn_to_pfn(unsigned long mfn)
 {
-       extern unsigned long max_mapnr;
        unsigned long pfn;
 
        if (xen_feature(XENFEAT_auto_translated_physmap))
@@ -92,7 +93,6 @@ static inline unsigned long mfn_to_pfn(u
  */
 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 < max_mapnr)
            && !xen_feature(XENFEAT_auto_translated_physmap)
@@ -103,6 +103,7 @@ static inline unsigned long mfn_to_local
 
 static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
 {
+       BUG_ON(max_mapnr && pfn >= max_mapnr);
        if (xen_feature(XENFEAT_auto_translated_physmap)) {
                BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY);
                return;
@@ -124,6 +125,20 @@ static inline paddr_t machine_to_phys(ma
        return phys;
 }
 
+#ifdef CONFIG_X86_PAE
+static inline paddr_t pte_phys_to_machine(paddr_t phys)
+{
+       /*
+        * In PAE mode, the NX bit needs to be dealt with in the value
+        * passed to pfn_to_mfn(). On x86_64, we need to mask it off,
+        * but for i386 the conversion to ulong for the argument will
+        * clip it off.
+        */
+       maddr_t machine = pfn_to_mfn(phys >> PAGE_SHIFT);
+       machine = (machine << PAGE_SHIFT) | (phys & ~PHYSICAL_PAGE_MASK);
+       return machine;
+}
+
 static inline paddr_t pte_machine_to_phys(maddr_t machine)
 {
        /*
@@ -136,6 +151,7 @@ static inline paddr_t pte_machine_to_phy
        phys = (phys << PAGE_SHIFT) | (machine & ~PHYSICAL_PAGE_MASK);
        return phys;
 }
+#endif
 
 #else /* !CONFIG_XEN */
 
@@ -146,7 +162,6 @@ static inline paddr_t pte_machine_to_phy
 #define phys_to_machine_mapping_valid(pfn) (1)
 #define phys_to_machine(phys) ((maddr_t)(phys))
 #define machine_to_phys(mach) ((paddr_t)(mach))
-#define pte_machine_to_phys(mach) ((paddr_t)(mach))
 
 #endif /* !CONFIG_XEN */
 
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h Sun Feb 18 
16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h Tue Feb 20 
12:58:22 2007 -0700
@@ -28,6 +28,13 @@
 #include <asm/bug.h>
 #include <xen/interface/xen.h>
 #include <xen/features.h>
+
+/*
+ * Need to repeat this here in order to not include pgtable.h (which in turn
+ * depends on definitions made here), but to be able to use the symbolic
+ * below. The preprocessor will warn if the two definitions aren't identical.
+ */
+#define _PAGE_PRESENT  0x001
 
 #define arch_free_page(_page,_order)           \
 ({     int foreign = PageForeign(_page);       \
@@ -81,39 +88,37 @@ typedef struct { unsigned long long pgpr
 #define pgprot_val(x)  ((x).pgprot)
 #include <asm/maddr.h>
 #define __pte(x) ({ unsigned long long _x = (x);        \
-    if (_x & 1) _x = phys_to_machine(_x);               \
+    if (_x & _PAGE_PRESENT) _x = pte_phys_to_machine(_x);   \
     ((pte_t) {(unsigned long)(_x), (unsigned long)(_x>>32)}); })
 #define __pgd(x) ({ unsigned long long _x = (x); \
-    (((_x)&1) ? ((pgd_t) {phys_to_machine(_x)}) : ((pgd_t) {(_x)})); })
+    (pgd_t) {((_x) & _PAGE_PRESENT) ? pte_phys_to_machine(_x) : (_x)}; })
 #define __pmd(x) ({ unsigned long long _x = (x); \
-    (((_x)&1) ? ((pmd_t) {phys_to_machine(_x)}) : ((pmd_t) {(_x)})); })
+    (pmd_t) {((_x) & _PAGE_PRESENT) ? pte_phys_to_machine(_x) : (_x)}; })
+static inline unsigned long long pte_val_ma(pte_t x)
+{
+       return ((unsigned long long)x.pte_high << 32) | x.pte_low;
+}
 static inline unsigned long long pte_val(pte_t x)
 {
-       unsigned long long ret;
-
-       if (x.pte_low) {
-               ret = x.pte_low | (unsigned long long)x.pte_high << 32;
-               ret = pte_machine_to_phys(ret) | 1;
-       } else {
-               ret = 0;
-       }
+       unsigned long long ret = pte_val_ma(x);
+       if (x.pte_low & _PAGE_PRESENT) ret = pte_machine_to_phys(ret);
        return ret;
 }
 static inline unsigned long long pmd_val(pmd_t x)
 {
        unsigned long long ret = x.pmd;
-       if (ret) ret = pte_machine_to_phys(ret) | 1;
+#ifdef CONFIG_XEN_COMPAT_030002
+       if (ret) ret = pte_machine_to_phys(ret) | _PAGE_PRESENT;
+#else
+       if (ret & _PAGE_PRESENT) ret = pte_machine_to_phys(ret);
+#endif
        return ret;
 }
 static inline unsigned long long pgd_val(pgd_t x)
 {
        unsigned long long ret = x.pgd;
-       if (ret) ret = pte_machine_to_phys(ret) | 1;
-       return ret;
-}
-static inline unsigned long long pte_val_ma(pte_t x)
-{
-       return (unsigned long long)x.pte_high << 32 | x.pte_low;
+       if (ret & _PAGE_PRESENT) ret = pte_machine_to_phys(ret);
+       return ret;
 }
 #define HPAGE_SHIFT    21
 #else
@@ -123,23 +128,23 @@ typedef struct { unsigned long pgprot; }
 #define pgprot_val(x)  ((x).pgprot)
 #include <asm/maddr.h>
 #define boot_pte_t pte_t /* or would you rather have a typedef */
-#define pte_val(x)     (((x).pte_low & 1) ? \
-                        pte_machine_to_phys((x).pte_low) : \
+#define pte_val(x)     (((x).pte_low & _PAGE_PRESENT) ? \
+                        machine_to_phys((x).pte_low) : \
                         (x).pte_low)
 #define pte_val_ma(x)  ((x).pte_low)
 #define __pte(x) ({ unsigned long _x = (x); \
-    (((_x)&1) ? ((pte_t) {phys_to_machine(_x)}) : ((pte_t) {(_x)})); })
+    (pte_t) {((_x) & _PAGE_PRESENT) ? phys_to_machine(_x) : (_x)}; })
 #define __pgd(x) ({ unsigned long _x = (x); \
-    (((_x)&1) ? ((pgd_t) {phys_to_machine(_x)}) : ((pgd_t) {(_x)})); })
+    (pgd_t) {((_x) & _PAGE_PRESENT) ? phys_to_machine(_x) : (_x)}; })
 static inline unsigned long pgd_val(pgd_t x)
 {
        unsigned long ret = x.pgd;
-       if (ret) ret = pte_machine_to_phys(ret) | 1;
+       if (ret & _PAGE_PRESENT) ret = machine_to_phys(ret);
        return ret;
 }
 #define HPAGE_SHIFT    22
 #endif
-#define PTE_MASK       PAGE_MASK
+#define PTE_MASK       PHYSICAL_PAGE_MASK
 
 #ifdef CONFIG_HUGETLB_PAGE
 #define HPAGE_SIZE     ((1UL) << HPAGE_SHIFT)
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level.h       
Sun Feb 18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level.h       
Tue Feb 20 12:58:22 2007 -0700
@@ -38,8 +38,11 @@
 
 #define ptep_get_and_clear(mm,addr,xp) __pte_ma(xchg(&(xp)->pte_low, 0))
 #define pte_same(a, b)         ((a).pte_low == (b).pte_low)
-#define pte_mfn(_pte) ((_pte).pte_low >> PAGE_SHIFT)
-#define pte_pfn(_pte) mfn_to_local_pfn(pte_mfn(_pte))
+#define __pte_mfn(_pte) ((_pte).pte_low >> PAGE_SHIFT)
+#define pte_mfn(_pte) ((_pte).pte_low & _PAGE_PRESENT ? \
+       __pte_mfn(_pte) : pfn_to_mfn(__pte_mfn(_pte)))
+#define pte_pfn(_pte) ((_pte).pte_low & _PAGE_PRESENT ? \
+       mfn_to_local_pfn(__pte_mfn(_pte)) : __pte_mfn(_pte))
 
 #define pte_page(_pte) pfn_to_page(pte_pfn(_pte))
 
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level.h       
Sun Feb 18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level.h       
Tue Feb 20 12:58:22 2007 -0700
@@ -52,22 +52,14 @@ static inline int pte_exec_kernel(pte_t 
  */
 #define __HAVE_ARCH_SET_PTE_ATOMIC
 
-#if 1
-/* use writable pagetables */
 static inline void set_pte(pte_t *ptep, pte_t pte)
 {
        ptep->pte_high = pte.pte_high;
        smp_wmb();
        ptep->pte_low = pte.pte_low;
 }
-# define set_pte_atomic(pteptr,pteval) \
+#define set_pte_atomic(pteptr,pteval) \
                set_64bit((unsigned long long *)(pteptr),pte_val_ma(pteval))
-#else
-/* no writable pagetables */
-# define set_pte(pteptr,pteval)                                \
-               xen_l1_entry_update((pteptr), (pteval))
-# define set_pte_atomic(pteptr,pteval) set_pte(pteptr,pteval)
-#endif
 
 #define set_pte_at(_mm,addr,ptep,pteval) do {                          \
        if (((_mm) != current->mm && (_mm) != &init_mm) ||              \
@@ -145,21 +137,24 @@ static inline int pte_none(pte_t pte)
        return !pte.pte_low && !pte.pte_high;
 }
 
-#define pte_mfn(_pte) (((_pte).pte_low >> PAGE_SHIFT) |\
-                      (((_pte).pte_high & 0xfff) << (32-PAGE_SHIFT)))
-#define pte_pfn(_pte) mfn_to_local_pfn(pte_mfn(_pte))
+#define __pte_mfn(_pte) (((_pte).pte_low >> PAGE_SHIFT) | \
+                        ((_pte).pte_high << (32-PAGE_SHIFT)))
+#define pte_mfn(_pte) ((_pte).pte_low & _PAGE_PRESENT ? \
+       __pte_mfn(_pte) : pfn_to_mfn(__pte_mfn(_pte)))
+#define pte_pfn(_pte) ((_pte).pte_low & _PAGE_PRESENT ? \
+       mfn_to_local_pfn(__pte_mfn(_pte)) : __pte_mfn(_pte))
 
 extern unsigned long long __supported_pte_mask;
 
 static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
 {
-       return pfn_pte_ma(pfn_to_mfn(page_nr), pgprot);
+       return __pte((((unsigned long long)page_nr << PAGE_SHIFT) |
+                       pgprot_val(pgprot)) & __supported_pte_mask);
 }
 
 static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot)
 {
-       BUG(); panic("needs review");
-       return __pmd((((unsigned long long)page_nr << PAGE_SHIFT) | \
+       return __pmd((((unsigned long long)page_nr << PAGE_SHIFT) |
                        pgprot_val(pgprot)) & __supported_pte_mask);
 }
 
@@ -180,6 +175,6 @@ static inline pmd_t pfn_pmd(unsigned lon
 
 #define __pmd_free_tlb(tlb, x)         do { } while (0)
 
-#define vmalloc_sync_all() ((void)0)
+void vmalloc_sync_all(void);
 
 #endif /* _I386_PGTABLE_3LEVEL_H */
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable.h      Sun Feb 
18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable.h      Tue Feb 
20 12:58:22 2007 -0700
@@ -315,18 +315,19 @@ static inline void clone_pgd_range(pgd_t
 
 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
-       pte.pte_low &= _PAGE_CHG_MASK;
-       pte.pte_low |= pgprot_val(newprot);
+       /*
+        * Since this might change the present bit (which controls whether
+        * a pte_t object has undergone p2m translation), we must use
+        * pte_val() on the input pte and __pte() for the return value.
+        */
+       paddr_t pteval = pte_val(pte);
+
+       pteval &= _PAGE_CHG_MASK;
+       pteval |= pgprot_val(newprot);
 #ifdef CONFIG_X86_PAE
-       /*
-        * Chop off the NX bit (if present), and add the NX portion of
-        * the newprot (if present):
-        */
-       pte.pte_high &= ~(1 << (_PAGE_BIT_NX - 32));
-       pte.pte_high |= (pgprot_val(newprot) >> 32) & \
-                                       (__supported_pte_mask >> 32);
-#endif
-       return pte;
+       pteval &= __supported_pte_mask;
+#endif
+       return __pte(pteval);
 }
 
 #define pmd_large(pmd) \
@@ -432,12 +433,15 @@ extern void noexec_setup(const char *str
 #define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
        do {                                                              \
                if (__dirty) {                                            \
-                       if ( likely((__vma)->vm_mm == current->mm) ) {    \
-                           BUG_ON(HYPERVISOR_update_va_mapping((__address), 
(__entry), UVMF_INVLPG|UVMF_MULTI|(unsigned 
long)((__vma)->vm_mm->cpu_vm_mask.bits))); \
-                       } else {                                          \
-                            xen_l1_entry_update((__ptep), (__entry)); \
-                           flush_tlb_page((__vma), (__address));         \
-                       }                                                 \
+                       if ( likely((__vma)->vm_mm == current->mm) ) {    \
+                               BUG_ON(HYPERVISOR_update_va_mapping(__address, \
+                                       __entry,                          \
+                                       (unsigned 
long)(__vma)->vm_mm->cpu_vm_mask.bits| \
+                                       UVMF_INVLPG|UVMF_MULTI));         \
+                       } else {                                          \
+                               xen_l1_entry_update(__ptep, __entry);     \
+                               flush_tlb_page(__vma, __address);         \
+                       }                                                 \
                }                                                         \
        } while (0)
 
diff -r 04c23c1ef888 -r d907467f08cd 
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       Sun Feb 
18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h       Tue Feb 
20 12:58:22 2007 -0700
@@ -100,8 +100,7 @@ __asm__ __volatile__ ("movw %%dx,%1\n\t"
 #define write_cr0(x) \
        __asm__ __volatile__("movl %0,%%cr0": :"r" (x))
 
-#define read_cr2() \
-       (HYPERVISOR_shared_info->vcpu_info[smp_processor_id()].arch.cr2)
+#define read_cr2() (current_vcpu_info()->arch.cr2)
 #define write_cr2(x) \
        __asm__ __volatile__("movl %0,%%cr2": :"r" (x))
 
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/irqflags.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/irqflags.h   Sun Feb 
18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/irqflags.h   Tue Feb 
20 12:58:22 2007 -0700
@@ -15,12 +15,6 @@
  * Interrupt control:
  */
 
-#ifdef CONFIG_SMP
-#define __vcpu_id smp_processor_id()
-#else
-#define __vcpu_id 0
-#endif
-
 /*
  * The use of 'barrier' in the following reflects their use as local-lock
  * operations. Reentrancy must be prevented (e.g., __cli()) /before/ following
@@ -29,8 +23,7 @@
  * includes these barriers, for example.
  */
 
-#define __raw_local_save_flags()                                       \
-       (&HYPERVISOR_shared_info->vcpu_info[__vcpu_id])->evtchn_upcall_mask;
+#define __raw_local_save_flags() (current_vcpu_info()->evtchn_upcall_mask)
 
 #define raw_local_save_flags(flags) \
                do { (flags) = __raw_local_save_flags(); } while (0)
@@ -39,7 +32,7 @@ do {                                                          
        \
 do {                                                                   \
        vcpu_info_t *_vcpu;                                             \
        barrier();                                                      \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];          \
+       _vcpu = current_vcpu_info();            \
        if ((_vcpu->evtchn_upcall_mask = (x)) == 0) {                   \
                barrier(); /* unmask then check (avoid races) */        \
                if ( unlikely(_vcpu->evtchn_upcall_pending) )           \
@@ -76,9 +69,7 @@ static inline int raw_irqs_disabled_flag
 
 #define raw_local_irq_disable()                                                
\
 do {                                                                   \
-       vcpu_info_t *_vcpu;                                             \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];          \
-       _vcpu->evtchn_upcall_mask = 1;                                  \
+       current_vcpu_info()->evtchn_upcall_mask = 1;                            
        \
        barrier();                                                      \
 } while (0)
 
@@ -86,7 +77,7 @@ do {                                                          
        \
 do {                                                                   \
        vcpu_info_t *_vcpu;                                             \
        barrier();                                                      \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];          \
+       _vcpu = current_vcpu_info();            \
        _vcpu->evtchn_upcall_mask = 0;                                  \
        barrier(); /* unmask then check (avoid races) */                \
        if ( unlikely(_vcpu->evtchn_upcall_pending) )                   \
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/maddr.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/maddr.h      Sun Feb 
18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/maddr.h      Tue Feb 
20 12:58:22 2007 -0700
@@ -25,14 +25,15 @@ static inline unsigned long pfn_to_mfn(u
 {
        if (xen_feature(XENFEAT_auto_translated_physmap))
                return pfn;
-       return phys_to_machine_mapping[(unsigned int)(pfn)] &
-               ~FOREIGN_FRAME_BIT;
+       BUG_ON(end_pfn && pfn >= end_pfn);
+       return phys_to_machine_mapping[pfn] & ~FOREIGN_FRAME_BIT;
 }
 
 static inline int phys_to_machine_mapping_valid(unsigned long pfn)
 {
        if (xen_feature(XENFEAT_auto_translated_physmap))
                return 1;
+       BUG_ON(end_pfn && pfn >= end_pfn);
        return (phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY);
 }
 
@@ -96,6 +97,7 @@ static inline unsigned long mfn_to_local
 
 static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
 {
+       BUG_ON(end_pfn && pfn >= end_pfn);
        if (xen_feature(XENFEAT_auto_translated_physmap)) {
                BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY);
                return;
@@ -117,6 +119,14 @@ static inline paddr_t machine_to_phys(ma
        return phys;
 }
 
+static inline paddr_t pte_phys_to_machine(paddr_t phys)
+{
+       maddr_t machine;
+       machine = pfn_to_mfn((phys & PHYSICAL_PAGE_MASK) >> PAGE_SHIFT);
+       machine = (machine << PAGE_SHIFT) | (phys & ~PHYSICAL_PAGE_MASK);
+       return machine;
+}
+
 static inline paddr_t pte_machine_to_phys(maddr_t machine)
 {
        paddr_t phys;
@@ -134,7 +144,6 @@ static inline paddr_t pte_machine_to_phy
 #define phys_to_machine_mapping_valid(pfn) (1)
 #define phys_to_machine(phys) ((maddr_t)(phys))
 #define machine_to_phys(mach) ((paddr_t)(mach))
-#define pte_machine_to_phys(mach) ((paddr_t)(mach))
 
 #endif /* !CONFIG_XEN */
 
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h       Sun Feb 
18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h       Tue Feb 
20 12:58:22 2007 -0700
@@ -8,6 +8,13 @@
 #include <asm/bug.h>
 #endif
 #include <xen/interface/xen.h> 
+
+/*
+ * Need to repeat this here in order to not include pgtable.h (which in turn
+ * depends on definitions made here), but to be able to use the symbolic
+ * below. The preprocessor will warn if the two definitions aren't identical.
+ */
+#define _PAGE_PRESENT  0x001
 
 #define arch_free_page(_page,_order)           \
 ({     int foreign = PageForeign(_page);       \
@@ -95,28 +102,33 @@ typedef struct { unsigned long pgd; } pg
 
 typedef struct { unsigned long pgprot; } pgprot_t;
 
-#define pte_val(x)     (((x).pte & 1) ? pte_machine_to_phys((x).pte) : \
+#define pte_val(x)     (((x).pte & _PAGE_PRESENT) ? \
+                        pte_machine_to_phys((x).pte) : \
                         (x).pte)
 #define pte_val_ma(x)  ((x).pte)
 
 static inline unsigned long pmd_val(pmd_t x)
 {
        unsigned long ret = x.pmd;
-       if (ret) ret = pte_machine_to_phys(ret);
+#ifdef CONFIG_XEN_COMPAT_030002
+       if (ret) ret = pte_machine_to_phys(ret) | _PAGE_PRESENT;
+#else
+       if (ret & _PAGE_PRESENT) ret = pte_machine_to_phys(ret);
+#endif
        return ret;
 }
 
 static inline unsigned long pud_val(pud_t x)
 {
        unsigned long ret = x.pud;
-       if (ret) ret = pte_machine_to_phys(ret);
+       if (ret & _PAGE_PRESENT) ret = pte_machine_to_phys(ret);
        return ret;
 }
 
 static inline unsigned long pgd_val(pgd_t x)
 {
        unsigned long ret = x.pgd;
-       if (ret) ret = pte_machine_to_phys(ret);
+       if (ret & _PAGE_PRESENT) ret = pte_machine_to_phys(ret);
        return ret;
 }
 
@@ -124,25 +136,25 @@ static inline unsigned long pgd_val(pgd_
 
 static inline pte_t __pte(unsigned long x)
 {
-       if (x & 1) x = phys_to_machine(x);
+       if (x & _PAGE_PRESENT) x = pte_phys_to_machine(x);
        return ((pte_t) { (x) });
 }
 
 static inline pmd_t __pmd(unsigned long x)
 {
-       if ((x & 1)) x = phys_to_machine(x);
+       if (x & _PAGE_PRESENT) x = pte_phys_to_machine(x);
        return ((pmd_t) { (x) });
 }
 
 static inline pud_t __pud(unsigned long x)
 {
-       if ((x & 1)) x = phys_to_machine(x);
+       if (x & _PAGE_PRESENT) x = pte_phys_to_machine(x);
        return ((pud_t) { (x) });
 }
 
 static inline pgd_t __pgd(unsigned long x)
 {
-       if ((x & 1)) x = phys_to_machine(x);
+       if (x & _PAGE_PRESENT) x = pte_phys_to_machine(x);
        return ((pgd_t) { (x) });
 }
 
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h    Sun Feb 
18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h    Tue Feb 
20 12:58:22 2007 -0700
@@ -302,19 +302,20 @@ static inline unsigned long pud_bad(pud_
 
 #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
 
-#define pte_mfn(_pte) (((_pte).pte & PTE_MASK) >> PAGE_SHIFT)
-#define pte_pfn(_pte) mfn_to_local_pfn(pte_mfn(_pte))
+#define __pte_mfn(_pte) (((_pte).pte & PTE_MASK) >> PAGE_SHIFT)
+#define pte_mfn(_pte) ((_pte).pte & _PAGE_PRESENT ? \
+       __pte_mfn(_pte) : pfn_to_mfn(__pte_mfn(_pte)))
+#define pte_pfn(_pte) ((_pte).pte & _PAGE_PRESENT ? \
+       mfn_to_local_pfn(__pte_mfn(_pte)) : __pte_mfn(_pte))
 
 #define pte_page(x)    pfn_to_page(pte_pfn(x))
 
 static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
 {
-       pte_t pte;
-        
-       (pte).pte = (pfn_to_mfn(page_nr) << PAGE_SHIFT);
-       (pte).pte |= pgprot_val(pgprot);
-       (pte).pte &= __supported_pte_mask;
-       return pte;
+       unsigned long pte = page_nr << PAGE_SHIFT;
+       pte |= pgprot_val(pgprot);
+       pte &= __supported_pte_mask;
+       return __pte(pte);
 }
 
 /*
@@ -446,18 +447,25 @@ static inline pud_t *pud_offset_k(pgd_t 
 /* physical address -> PTE */
 static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
 { 
-       pte_t pte;
-       (pte).pte = physpage | pgprot_val(pgprot); 
-       return pte; 
+       unsigned long pteval;
+       pteval = physpage | pgprot_val(pgprot);
+       return __pte(pteval);
 }
  
 /* Change flags of a PTE */
 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 { 
-        (pte).pte &= _PAGE_CHG_MASK;
-       (pte).pte |= pgprot_val(newprot);
-       (pte).pte &= __supported_pte_mask;
-       return pte; 
+       /*
+        * Since this might change the present bit (which controls whether
+        * a pte_t object has undergone p2m translation), we must use
+        * pte_val() on the input pte and __pte() for the return value.
+        */
+       unsigned long pteval = pte_val(pte);
+
+       pteval &= _PAGE_CHG_MASK;
+       pteval |= pgprot_val(newprot);
+       pteval &= __supported_pte_mask;
+       return __pte(pteval);
 }
 
 #define pte_index(address) \
@@ -479,24 +487,18 @@ static inline pte_t pte_modify(pte_t pte
  * race with other CPU's that might be updating the dirty
  * bit at the same time. */
 #define  __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
-#if 0
 #define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
        do {                                                              \
                if (__dirty) {                                            \
-                       set_pte(__ptep, __entry);                         \
-                       flush_tlb_page(__vma, __address);                 \
-               }                                                         \
-       } while (0)
-#endif
-#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
-       do {                                                              \
-               if (__dirty) {                                            \
-                       if ( likely((__vma)->vm_mm == current->mm) ) {    \
-                           BUG_ON(HYPERVISOR_update_va_mapping((__address), 
(__entry), UVMF_INVLPG|UVMF_MULTI|(unsigned 
long)((__vma)->vm_mm->cpu_vm_mask.bits))); \
-                       } else {                                          \
-                            xen_l1_entry_update((__ptep), (__entry)); \
-                           flush_tlb_page((__vma), (__address));         \
-                       }                                                 \
+                       if ( likely((__vma)->vm_mm == current->mm) ) {    \
+                               BUG_ON(HYPERVISOR_update_va_mapping(__address, \
+                                       __entry,                          \
+                                       (unsigned 
long)(__vma)->vm_mm->cpu_vm_mask.bits| \
+                                               UVMF_INVLPG|UVMF_MULTI)); \
+                       } else {                                          \
+                               xen_l1_entry_update(__ptep, __entry);     \
+                               flush_tlb_page(__vma, __address);         \
+                       }                                                 \
                }                                                         \
        } while (0)
 
diff -r 04c23c1ef888 -r d907467f08cd linux-2.6-xen-sparse/include/linux/pfn.h
--- a/linux-2.6-xen-sparse/include/linux/pfn.h  Sun Feb 18 16:13:13 2007 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-#ifndef _LINUX_PFN_H_
-#define _LINUX_PFN_H_
-
-#define PFN_ALIGN(x)   (((unsigned long long)(x) + (PAGE_SIZE - 1)) & 
PAGE_MASK)
-#define PFN_UP(x)      (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
-#define PFN_DOWN(x)    ((x) >> PAGE_SHIFT)
-#define PFN_PHYS(x)    ((unsigned long long)(x) << PAGE_SHIFT)
-
-#endif
diff -r 04c23c1ef888 -r d907467f08cd 
linux-2.6-xen-sparse/include/xen/driver_util.h
--- a/linux-2.6-xen-sparse/include/xen/driver_util.h    Sun Feb 18 16:13:13 
2007 -0700
+++ b/linux-2.6-xen-sparse/include/xen/driver_util.h    Tue Feb 20 12:58:22 
2007 -0700
@@ -9,8 +9,4 @@ extern struct vm_struct *alloc_vm_area(u
 extern struct vm_struct *alloc_vm_area(unsigned long size);
 extern void free_vm_area(struct vm_struct *area);
 
-/* Lock an area so that PTEs are accessible in the current address space. */
-extern void lock_vm_area(struct vm_struct *area);
-extern void unlock_vm_area(struct vm_struct *area);
-
 #endif /* __ASM_XEN_DRIVER_UTIL_H__ */
diff -r 04c23c1ef888 -r d907467f08cd linux-2.6-xen-sparse/include/xen/gnttab.h
--- a/linux-2.6-xen-sparse/include/xen/gnttab.h Sun Feb 18 16:13:13 2007 -0700
+++ b/linux-2.6-xen-sparse/include/xen/gnttab.h Tue Feb 20 12:58:22 2007 -0700
@@ -42,13 +42,6 @@
 #include <asm/maddr.h> /* maddr_t */
 #include <xen/interface/grant_table.h>
 #include <xen/features.h>
-
-/* NR_GRANT_FRAMES must be less than or equal to that configured in Xen */
-#ifdef __ia64__
-#define NR_GRANT_FRAMES 1
-#else
-#define NR_GRANT_FRAMES 4
-#endif
 
 struct gnttab_free_callback {
        struct gnttab_free_callback *next;
@@ -109,12 +102,6 @@ void gnttab_grant_foreign_transfer_ref(g
 void gnttab_grant_foreign_transfer_ref(grant_ref_t, domid_t domid,
                                       unsigned long pfn);
 
-#ifdef __ia64__
-#define gnttab_map_vaddr(map) __va(map.dev_bus_addr)
-#else
-#define gnttab_map_vaddr(map) ((void *)(map.host_virt_addr))
-#endif
-
 int gnttab_suspend(void);
 int gnttab_resume(void);
 
diff -r 04c23c1ef888 -r d907467f08cd 
patches/linux-2.6.18/x86-elfnote-as-preprocessor-macro.patch
--- a/patches/linux-2.6.18/x86-elfnote-as-preprocessor-macro.patch      Sun Feb 
18 16:13:13 2007 -0700
+++ b/patches/linux-2.6.18/x86-elfnote-as-preprocessor-macro.patch      Tue Feb 
20 12:58:22 2007 -0700
@@ -1,7 +1,7 @@ diff -pruN ../orig-linux-2.6.18/include/
 diff -pruN ../orig-linux-2.6.18/include/linux/elfnote.h 
./include/linux/elfnote.h
 --- ../orig-linux-2.6.18/include/linux/elfnote.h       2007-01-12 
18:19:44.000000000 +0000
 +++ ./include/linux/elfnote.h  2007-01-12 18:21:02.000000000 +0000
-@@ -31,22 +31,24 @@
+@@ -31,22 +31,38 @@
  /*
   * Generate a structure with the same shape as Elf{32,64}_Nhdr (which
   * turn out to be the same size and shape), followed by the name and
@@ -25,9 +25,21 @@ diff -pruN ../orig-linux-2.6.18/include/
 -2:.align 4
 -3:\desc
 -4:.align 4
--.popsection
++#ifdef __STDC__
++#define ELFNOTE(name, type, desctype, descdata...) \
++.pushsection .note.name                       ;       \
++  .align 4                            ;       \
++  .long 2f - 1f               /* namesz */    ;       \
++  .long 4f - 3f               /* descsz */    ;       \
++  .long type                          ;       \
++1:.asciz #name                                ;       \
++2:.align 4                            ;       \
++3:desctype descdata                   ;       \
++4:.align 4                            ;       \
+ .popsection
 -.endm
-+#define ELFNOTE(name, type, desctype, descdata)       \
++#else /* !__STDC__, i.e. -traditional */
++#define ELFNOTE(name, type, desctype, descdata) \
 +.pushsection .note.name                       ;       \
 +  .align 4                            ;       \
 +  .long 2f - 1f               /* namesz */    ;       \
@@ -37,7 +49,8 @@ diff -pruN ../orig-linux-2.6.18/include/
 +2:.align 4                            ;       \
 +3:desctype descdata                   ;       \
 +4:.align 4                            ;       \
-+.popsection                           ;
++.popsection
++#endif /* __STDC__ */
  #else /* !__ASSEMBLER__ */
  #include <linux/elf.h>
  /*
diff -r 04c23c1ef888 -r d907467f08cd tools/blktap/drivers/Makefile
--- a/tools/blktap/drivers/Makefile     Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/blktap/drivers/Makefile     Tue Feb 20 12:58:22 2007 -0700
@@ -5,7 +5,7 @@ INCLUDES += -I.. -I../lib
 
 IBIN         = blktapctrl tapdisk
 QCOW_UTIL    = img2qcow qcow2raw qcow-create
-INST_DIR  = /usr/sbin
+INST_DIR     = /usr/sbin
 LIBAIO_DIR   = ../../libaio/src
 
 CFLAGS   += -Werror
@@ -17,7 +17,7 @@ CFLAGS   += -D_GNU_SOURCE
 
 # Get gcc to generate the dependencies for us.
 CFLAGS   += -Wp,-MD,.$(@F).d
-DEPS     = .*.d
+DEPS      = .*.d
 
 THREADLIB := -lpthread -lz
 LIBS      := -L. -L.. -L../lib
@@ -29,10 +29,10 @@ LIBS      += -L$(XEN_XENSTORE) -lxenstor
 
 AIOLIBS   := $(LIBAIO_DIR)/libaio.a
 
-BLK-OBJS  := block-aio.o 
-BLK-OBJS  += block-sync.o 
+BLK-OBJS  := block-aio.o
+BLK-OBJS  += block-sync.o
 BLK-OBJS  += block-vmdk.o
-BLK-OBJS  += block-ram.o 
+BLK-OBJS  += block-ram.o
 BLK-OBJS  += block-qcow.o
 BLK-OBJS  += aes.o
 
@@ -52,13 +52,13 @@ qcow-util: img2qcow qcow2raw qcow-create
 qcow-util: img2qcow qcow2raw qcow-create
 
 img2qcow qcow2raw qcow-create: %: $(BLK-OBJS)
-       $(CC) $(CFLAGS) -o $* $(BLK-OBJS) $*.c $(AIOLIBS)  $(LIBS)
+       $(CC) $(CFLAGS) -o $* $(BLK-OBJS) $*.c $(AIOLIBS) $(LIBS)
 
 install: all
-       $(INSTALL_PROG) $(IBIN) $(QCOW_UTIL) $(DESTDIR)$(INST_DIR)
+       $(INSTALL_PROG) $(IBIN) $(QCOW_UTIL) $(VHD_UTIL) $(DESTDIR)$(INST_DIR)
 
 clean:
-       rm -rf *.o *~ $(DEPS) xen TAGS $(IBIN) $(LIB) $(QCOW_UTIL)
+       rm -rf *.o *~ $(DEPS) xen TAGS $(IBIN) $(LIB) $(QCOW_UTIL) $(VHD_UTIL)
 
 .PHONY: clean install
 
diff -r 04c23c1ef888 -r d907467f08cd tools/blktap/drivers/block-aio.c
--- a/tools/blktap/drivers/block-aio.c  Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/blktap/drivers/block-aio.c  Tue Feb 20 12:58:22 2007 -0700
@@ -58,6 +58,7 @@ struct pending_aio {
        td_callback_t cb;
        int id;
        void *private;
+       uint64_t lsec;
 };
 
 struct tdaio_state {
@@ -139,12 +140,23 @@ static int get_image_info(struct td_stat
        return 0;
 }
 
+static inline void init_fds(struct disk_driver *dd)
+{
+       int i;
+       struct tdaio_state *prv = (struct tdaio_state *)dd->private;
+
+       for(i = 0; i < MAX_IOFD; i++) 
+               dd->io_fd[i] = 0;
+
+       dd->io_fd[0] = prv->poll_fd;
+}
+
 /* Open the disk file and initialize aio state. */
-int tdaio_open (struct td_state *s, const char *name)
+int tdaio_open (struct disk_driver *dd, const char *name)
 {
        int i, fd, ret = 0;
-       struct tdaio_state *prv = (struct tdaio_state *)s->private;
-       s->private = prv;
+       struct td_state    *s   = dd->td_state;
+       struct tdaio_state *prv = (struct tdaio_state *)dd->private;
 
        DPRINTF("block-aio open('%s')", name);
        /* Initialize AIO */
@@ -194,18 +206,21 @@ int tdaio_open (struct td_state *s, cons
 
         prv->fd = fd;
 
+       init_fds(dd);
        ret = get_image_info(s, fd);
+
 done:
        return ret;     
 }
 
-int tdaio_queue_read(struct td_state *s, uint64_t sector,
-                              int nb_sectors, char *buf, td_callback_t cb,
-                              int id, void *private)
+int tdaio_queue_read(struct disk_driver *dd, uint64_t sector,
+                    int nb_sectors, char *buf, td_callback_t cb,
+                    int id, void *private)
 {
        struct   iocb *io;
        struct   pending_aio *pio;
-       struct   tdaio_state *prv = (struct tdaio_state *)s->private;
+       struct   td_state    *s   = dd->td_state;
+       struct   tdaio_state *prv = (struct tdaio_state *)dd->private;
        int      size    = nb_sectors * s->sector_size;
        uint64_t offset  = sector * (uint64_t)s->sector_size;
        long     ioidx;
@@ -219,22 +234,24 @@ int tdaio_queue_read(struct td_state *s,
        pio->cb = cb;
        pio->id = id;
        pio->private = private;
+       pio->lsec = sector;
        
        io_prep_pread(io, prv->fd, buf, size, offset);
        io->data = (void *)ioidx;
        
        prv->iocb_queue[prv->iocb_queued++] = io;
-       
-       return 0;
-}
-                       
-int tdaio_queue_write(struct td_state *s, uint64_t sector,
-                              int nb_sectors, char *buf, td_callback_t cb,
-                              int id, void *private)
+
+       return 0;
+}
+                       
+int tdaio_queue_write(struct disk_driver *dd, uint64_t sector,
+                     int nb_sectors, char *buf, td_callback_t cb,
+                     int id, void *private)
 {
        struct   iocb *io;
        struct   pending_aio *pio;
-       struct   tdaio_state *prv = (struct tdaio_state *)s->private;
+       struct   td_state    *s   = dd->td_state;
+       struct   tdaio_state *prv = (struct tdaio_state *)dd->private;
        int      size    = nb_sectors * s->sector_size;
        uint64_t offset  = sector * (uint64_t)s->sector_size;
        long     ioidx;
@@ -248,19 +265,20 @@ int tdaio_queue_write(struct td_state *s
        pio->cb = cb;
        pio->id = id;
        pio->private = private;
+       pio->lsec = sector;
        
        io_prep_pwrite(io, prv->fd, buf, size, offset);
        io->data = (void *)ioidx;
        
        prv->iocb_queue[prv->iocb_queued++] = io;
-       
-       return 0;
-}
-                       
-int tdaio_submit(struct td_state *s)
+
+       return 0;
+}
+                       
+int tdaio_submit(struct disk_driver *dd)
 {
        int ret;
-       struct   tdaio_state *prv = (struct tdaio_state *)s->private;
+       struct tdaio_state *prv = (struct tdaio_state *)dd->private;
 
        ret = io_submit(prv->aio_ctx, prv->iocb_queued, prv->iocb_queue);
        
@@ -269,38 +287,24 @@ int tdaio_submit(struct td_state *s)
        /* Success case: */
        prv->iocb_queued = 0;
        
-       return ret;
-}
-
-int *tdaio_get_fd(struct td_state *s)
-{
-       struct tdaio_state *prv = (struct tdaio_state *)s->private;
-       int *fds, i;
-
-       fds = malloc(sizeof(int) * MAX_IOFD);
-       /*initialise the FD array*/
-       for(i=0;i<MAX_IOFD;i++) fds[i] = 0;
-
-       fds[0] = prv->poll_fd;
-
-       return fds;     
-}
-
-int tdaio_close(struct td_state *s)
-{
-       struct tdaio_state *prv = (struct tdaio_state *)s->private;
+       return 0;
+}
+
+int tdaio_close(struct disk_driver *dd)
+{
+       struct tdaio_state *prv = (struct tdaio_state *)dd->private;
        
        io_destroy(prv->aio_ctx);
        close(prv->fd);
-       
-       return 0;
-}
-
-int tdaio_do_callbacks(struct td_state *s, int sid)
+
+       return 0;
+}
+
+int tdaio_do_callbacks(struct disk_driver *dd, int sid)
 {
        int ret, i, rsp = 0;
        struct io_event *ep;
-       struct tdaio_state *prv = (struct tdaio_state *)s->private;
+       struct tdaio_state *prv = (struct tdaio_state *)dd->private;
 
        /* Non-blocking test for completed io. */
        ret = io_getevents(prv->aio_ctx, 0, MAX_AIO_REQS, prv->aio_events,
@@ -311,22 +315,34 @@ int tdaio_do_callbacks(struct td_state *
                struct pending_aio *pio;
                
                pio = &prv->pending_aio[(long)io->data];
-               rsp += pio->cb(s, ep->res == io->u.c.nbytes ? 0 : 1,
+               rsp += pio->cb(dd, ep->res == io->u.c.nbytes ? 0 : 1,
+                              pio->lsec, io->u.c.nbytes >> 9, 
                               pio->id, pio->private);
 
                prv->iocb_free[prv->iocb_free_count++] = io;
        }
        return rsp;
 }
-       
+
+int tdaio_has_parent(struct disk_driver *dd)
+{
+       return 0;
+}
+
+int tdaio_get_parent(struct disk_driver *dd, struct disk_driver *parent)
+{
+       return -EINVAL;
+}
+
 struct tap_disk tapdisk_aio = {
-       "tapdisk_aio",
-       sizeof(struct tdaio_state),
-       tdaio_open,
-       tdaio_queue_read,
-       tdaio_queue_write,
-       tdaio_submit,
-       tdaio_get_fd,
-       tdaio_close,
-       tdaio_do_callbacks,
+       .disk_type          = "tapdisk_aio",
+       .private_data_size  = sizeof(struct tdaio_state),
+       .td_open            = tdaio_open,
+       .td_queue_read      = tdaio_queue_read,
+       .td_queue_write     = tdaio_queue_write,
+       .td_submit          = tdaio_submit,
+       .td_has_parent      = tdaio_has_parent,
+       .td_get_parent      = tdaio_get_parent,
+       .td_close           = tdaio_close,
+       .td_do_callbacks    = tdaio_do_callbacks,
 };
diff -r 04c23c1ef888 -r d907467f08cd tools/blktap/drivers/block-qcow.c
--- a/tools/blktap/drivers/block-qcow.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/blktap/drivers/block-qcow.c Tue Feb 20 12:58:22 2007 -0700
@@ -55,7 +55,6 @@
 
 /******AIO DEFINES******/
 #define REQUEST_ASYNC_FD 1
-#define MAX_QCOW_IDS  0xFFFF
 #define MAX_AIO_REQS (MAX_REQUESTS * MAX_SEGMENTS_PER_REQ)
 
 struct pending_aio {
@@ -65,7 +64,6 @@ struct pending_aio {
        int nb_sectors;
        char *buf;
        uint64_t sector;
-       int qcow_idx;
 };
 
 #define IOCB_IDX(_s, _io) ((_io) - (_s)->iocb_list)
@@ -115,9 +113,9 @@ struct tdqcow_state {
 struct tdqcow_state {
         int fd;                        /*Main Qcow file descriptor */
        uint64_t fd_end;               /*Store a local record of file length */
-       int bfd;                       /*Backing file descriptor*/
        char *name;                    /*Record of the filename*/
-       int poll_pipe[2];              /*dummy fd for polling on */
+       uint32_t backing_file_size;
+       uint64_t backing_file_offset;
        int encrypted;                 /*File contents are encrypted or plain*/
        int cluster_bits;              /*Determines length of cluster as 
                                        *indicated by file hdr*/
@@ -149,7 +147,6 @@ struct tdqcow_state {
        AES_KEY aes_decrypt_key;       /*AES key*/
         /* libaio state */
         io_context_t       aio_ctx;
-       int                nr_reqs [MAX_QCOW_IDS];
         struct iocb        iocb_list  [MAX_AIO_REQS];
         struct iocb       *iocb_free  [MAX_AIO_REQS];
         struct pending_aio pending_aio[MAX_AIO_REQS];
@@ -162,10 +159,11 @@ struct tdqcow_state {
 
 static int decompress_cluster(struct tdqcow_state *s, uint64_t cluster_offset);
 
-static int init_aio_state(struct td_state *bs)
+static int init_aio_state(struct disk_driver *dd)
 {
         int i;
-       struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
+       struct td_state     *bs = dd->td_state;
+       struct tdqcow_state  *s = (struct tdqcow_state *)dd->private;
         long     ioidx;
 
         /*Initialize Locking bitmap*/
@@ -202,8 +200,7 @@ static int init_aio_state(struct td_stat
 
         for (i=0;i<MAX_AIO_REQS;i++)
                 s->iocb_free[i] = &s->iocb_list[i];
-       for (i=0;i<MAX_QCOW_IDS;i++)
-               s->nr_reqs[i] = 0;
+
         DPRINTF("AIO state initialised\n");
 
         return 0;
@@ -238,7 +235,10 @@ static uint32_t gen_cksum(char *ptr, int
 
        if(!md) return 0;
 
-       if (MD5((unsigned char *)ptr, len, md) != md) return 0;
+       if (MD5((unsigned char *)ptr, len, md) != md) {
+               free(md);
+               return 0;
+       }
 
        memcpy(&ret, md, sizeof(uint32_t));
        free(md);
@@ -247,26 +247,42 @@ static uint32_t gen_cksum(char *ptr, int
 
 static int get_filesize(char *filename, uint64_t *size, struct stat *st)
 {
-       int blockfd;
+       int fd;
+       QCowHeader header;
 
        /*Set to the backing file size*/
+       fd = open(filename, O_RDONLY);
+       if (fd < 0)
+               return -1;
+       if (read(fd, &header, sizeof(header)) < sizeof(header)) {
+               close(fd);
+               return -1;
+       }
+       close(fd);
+       
+       be32_to_cpus(&header.magic);
+       be64_to_cpus(&header.size);
+       if (header.magic == QCOW_MAGIC) {
+               *size = header.size >> SECTOR_SHIFT;
+               return 0;
+       }
+
        if(S_ISBLK(st->st_mode)) {
-               blockfd = open(filename, O_RDONLY);
-               if (blockfd < 0)
+               fd = open(filename, O_RDONLY);
+               if (fd < 0)
                        return -1;
-               if (ioctl(blockfd,BLKGETSIZE,size)!=0) {
+               if (ioctl(fd,BLKGETSIZE,size)!=0) {
                        printf("Unable to get Block device size\n");
-                       close(blockfd);
+                       close(fd);
                        return -1;
                }
-               close(blockfd);
+               close(fd);
        } else *size = (st->st_size >> SECTOR_SHIFT);   
        return 0;
 }
 
-static int qcow_set_key(struct td_state *bs, const char *key)
-{
-       struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
+static int qcow_set_key(struct tdqcow_state *s, const char *key)
+{
        uint8_t keybuf[16];
        int len, i;
        
@@ -306,10 +322,9 @@ static int qcow_set_key(struct td_state 
        return 0;
 }
 
-static int async_read(struct tdqcow_state *s, int fd, int size, 
-                    uint64_t offset,
-                    char *buf, td_callback_t cb,
-                    int id, uint64_t sector, int qcow_idx, void *private)
+static int async_read(struct tdqcow_state *s, int size, 
+                     uint64_t offset, char *buf, td_callback_t cb,
+                     int id, uint64_t sector, void *private)
 {
         struct   iocb *io;
         struct   pending_aio *pio;
@@ -325,9 +340,8 @@ static int async_read(struct tdqcow_stat
        pio->nb_sectors = size/512;
        pio->buf = buf;
        pio->sector = sector;
-       pio->qcow_idx = qcow_idx;
-
-        io_prep_pread(io, fd, buf, size, offset);
+
+        io_prep_pread(io, s->fd, buf, size, offset);
         io->data = (void *)ioidx;
 
         s->iocb_queue[s->iocb_queued++] = io;
@@ -335,10 +349,9 @@ static int async_read(struct tdqcow_stat
         return 1;
 }
 
-static int async_write(struct tdqcow_state *s, int fd, int size, 
-                    uint64_t offset,
-                    char *buf, td_callback_t cb,
-                     int id, uint64_t sector, int qcow_idx, void *private)
+static int async_write(struct tdqcow_state *s, int size,
+                      uint64_t offset, char *buf, td_callback_t cb,
+                      int id, uint64_t sector, void *private)
 {
         struct   iocb *io;
         struct   pending_aio *pio;
@@ -354,9 +367,8 @@ static int async_write(struct tdqcow_sta
        pio->nb_sectors = size/512;
        pio->buf = buf;
        pio->sector = sector;
-       pio->qcow_idx = qcow_idx;
-
-        io_prep_pwrite(io, fd, buf, size, offset);
+
+        io_prep_pwrite(io, s->fd, buf, size, offset);
         io->data = (void *)ioidx;
 
         s->iocb_queue[s->iocb_queued++] = io;
@@ -381,17 +393,6 @@ static void aio_unlock(struct tdqcow_sta
 
        --s->sector_lock[sector];
        return;
-}
-
-/*TODO - Use a freelist*/
-static int get_free_idx(struct tdqcow_state *s)
-{
-       int i;
-       
-       for(i = 0; i < MAX_QCOW_IDS; i++) {
-               if(s->nr_reqs[i] == 0) return i;
-       }
-       return -1;
 }
 
 /* 
@@ -425,23 +426,23 @@ static int qtruncate(int fd, off_t lengt
 {
        int ret, i; 
        int current = 0, rem = 0;
-       int sectors = (length + DEFAULT_SECTOR_SIZE - 1)/DEFAULT_SECTOR_SIZE;
+       uint64_t sectors;
        struct stat st;
-       char buf[DEFAULT_SECTOR_SIZE];
+       char *buf;
 
        /* If length is greater than the current file len
         * we synchronously write zeroes to the end of the 
         * file, otherwise we truncate the length down
         */
-       memset(buf, 0x00, DEFAULT_SECTOR_SIZE);
        ret = fstat(fd, &st);
-       if (ret == -1)
+       if (ret == -1) 
                return -1;
        if (S_ISBLK(st.st_mode))
                return 0;
-
+       
+       sectors = (length + DEFAULT_SECTOR_SIZE - 1)/DEFAULT_SECTOR_SIZE;
        current = (st.st_size + DEFAULT_SECTOR_SIZE - 1)/DEFAULT_SECTOR_SIZE;
-       rem = st.st_size % DEFAULT_SECTOR_SIZE;
+       rem     = st.st_size % DEFAULT_SECTOR_SIZE;
 
        /* If we are extending this file, we write zeros to the end --
         * this tries to ensure that the extents allocated wind up being
@@ -449,28 +450,40 @@ static int qtruncate(int fd, off_t lengt
         */
        if(st.st_size < sectors * DEFAULT_SECTOR_SIZE) {
                /*We are extending the file*/
+               if ((ret = posix_memalign((void **)&buf, 
+                                         512, DEFAULT_SECTOR_SIZE))) {
+                       DPRINTF("posix_memalign failed: %d\n", ret);
+                       return -1;
+               }
+               memset(buf, 0x00, DEFAULT_SECTOR_SIZE);
                if (lseek(fd, 0, SEEK_END)==-1) {
-                       fprintf(stderr, 
-                               "Lseek EOF failed (%d), internal error\n",
+                       DPRINTF("Lseek EOF failed (%d), internal error\n",
                                errno);
+                       free(buf);
                        return -1;
                }
                if (rem) {
                        ret = write(fd, buf, rem);
-                       if (ret != rem)
+                       if (ret != rem) {
+                               DPRINTF("write failed: ret = %d, err = %s\n",
+                                       ret, strerror(errno));
+                               free(buf);
                                return -1;
+                       }
                }
                for (i = current; i < sectors; i++ ) {
                        ret = write(fd, buf, DEFAULT_SECTOR_SIZE);
-                       if (ret != DEFAULT_SECTOR_SIZE)
+                       if (ret != DEFAULT_SECTOR_SIZE) {
+                               DPRINTF("write failed: ret = %d, err = %s\n",
+                                       ret, strerror(errno));
+                               free(buf);
                                return -1;
-               }
-               
+                       }
+               }
+               free(buf);
        } else if(sparse && (st.st_size > sectors * DEFAULT_SECTOR_SIZE))
-               if (ftruncate(fd, sectors * DEFAULT_SECTOR_SIZE)==-1) {
-                       fprintf(stderr,
-                               "Ftruncate failed (%d), internal error\n",
-                                errno);
+               if (ftruncate(fd, (off_t)sectors * DEFAULT_SECTOR_SIZE)==-1) {
+                       DPRINTF("Ftruncate failed (%s)\n", strerror(errno));
                        return -1;
                }
        return 0;
@@ -490,12 +503,11 @@ static int qtruncate(int fd, off_t lengt
  *
  * return 0 if not allocated.
  */
-static uint64_t get_cluster_offset(struct td_state *bs,
+static uint64_t get_cluster_offset(struct tdqcow_state *s,
                                    uint64_t offset, int allocate,
                                    int compressed_size,
                                    int n_start, int n_end)
 {
-       struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
        int min_index, i, j, l1_index, l2_index, l2_sector, l1_sector;
        char *tmp_ptr, *tmp_ptr2, *l2_ptr, *l1_ptr;
        uint64_t l2_offset, *l2_table, cluster_offset, tmp;
@@ -550,8 +562,10 @@ static uint64_t get_cluster_offset(struc
                 * entry is written before blocks.
                 */
                lseek(s->fd, s->l1_table_offset + (l1_sector << 12), SEEK_SET);
-               if (write(s->fd, tmp_ptr, 4096) != 4096)
+               if (write(s->fd, tmp_ptr, 4096) != 4096) {
+                       free(tmp_ptr);
                        return 0;
+               }
                free(tmp_ptr);
 
                new_l2_table = 1;
@@ -716,9 +730,10 @@ found:
        return cluster_offset;
 }
 
-static void init_cluster_cache(struct td_state *bs)
-{
-       struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
+static void init_cluster_cache(struct disk_driver *dd)
+{
+       struct td_state     *bs = dd->td_state;
+       struct tdqcow_state *s  = (struct tdqcow_state *)dd->private;
        uint32_t count = 0;
        int i, cluster_entries;
 
@@ -727,22 +742,20 @@ static void init_cluster_cache(struct td
                cluster_entries, s->cluster_size);
 
        for (i = 0; i < bs->size; i += cluster_entries) {
-               if (get_cluster_offset(bs, i << 9, 0, 0, 0, 1)) count++;
+               if (get_cluster_offset(s, i << 9, 0, 0, 0, 1)) count++;
                if (count >= L2_CACHE_SIZE) return;
        }
        DPRINTF("Finished cluster initialisation, added %d entries\n", count);
        return;
 }
 
-static int qcow_is_allocated(struct td_state *bs, int64_t sector_num, 
+static int qcow_is_allocated(struct tdqcow_state *s, int64_t sector_num,
                              int nb_sectors, int *pnum)
 {
-       struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
-
        int index_in_cluster, n;
        uint64_t cluster_offset;
 
-       cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0);
+       cluster_offset = get_cluster_offset(s, sector_num << 9, 0, 0, 0, 0);
        index_in_cluster = sector_num & (s->cluster_sectors - 1);
        n = s->cluster_sectors - index_in_cluster;
        if (n > nb_sectors)
@@ -800,11 +813,23 @@ static int decompress_cluster(struct tdq
        return 0;
 }
 
+static inline void init_fds(struct disk_driver *dd)
+{
+       int i;
+       struct tdqcow_state *s = (struct tdqcow_state *)dd->private;
+
+       for(i = 0; i < MAX_IOFD; i++) 
+               dd->io_fd[i] = 0;
+
+       dd->io_fd[0] = s->poll_fd;
+}
+
 /* Open the disk file and initialize qcow state. */
-int tdqcow_open (struct td_state *bs, const char *name)
+int tdqcow_open (struct disk_driver *dd, const char *name)
 {
        int fd, len, i, shift, ret, size, l1_table_size;
-       struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
+       struct td_state     *bs = dd->td_state;
+       struct tdqcow_state *s  = (struct tdqcow_state *)dd->private;
        char *buf;
        QCowHeader *header;
        QCowHeader_ext *exthdr;
@@ -812,10 +837,6 @@ int tdqcow_open (struct td_state *bs, co
        uint64_t final_cluster = 0;
 
        DPRINTF("QCOW: Opening %s\n",name);
-       /* set up a pipe so that we can hand back a poll fd that won't fire.*/
-       ret = pipe(s->poll_pipe);
-       if (ret != 0)
-               return (0 - errno);
 
        fd = open(name, O_RDWR | O_DIRECT | O_LARGEFILE);
        if (fd < 0) {
@@ -826,7 +847,7 @@ int tdqcow_open (struct td_state *bs, co
        s->fd = fd;
        asprintf(&s->name,"%s", name);
 
-       ASSERT(sizeof(header) < 512);
+       ASSERT(sizeof(QCowHeader) + sizeof(QCowHeader_ext) < 512);
 
        ret = posix_memalign((void **)&buf, 512, 512);
        if (ret != 0) goto fail;
@@ -861,7 +882,9 @@ int tdqcow_open (struct td_state *bs, co
        s->cluster_alloc = s->l2_size;
        bs->size = header->size / 512;
        s->cluster_offset_mask = (1LL << (63 - s->cluster_bits)) - 1;
-       
+       s->backing_file_offset = header->backing_file_offset;
+       s->backing_file_size   = header->backing_file_size;
+
        /* read the level 1 table */
        shift = s->cluster_bits + s->l2_bits;
        s->l1_size = (header->size + (1LL << shift) - 1) >> shift;
@@ -887,7 +910,7 @@ int tdqcow_open (struct td_state *bs, co
        if (read(fd, s->l1_table, l1_table_size) != l1_table_size)
                goto fail;
 
-       for(i = 0;i < s->l1_size; i++) {
+       for(i = 0; i < s->l1_size; i++) {
                //be64_to_cpus(&s->l1_table[i]);
                //DPRINTF("L1[%d] => %llu\n", i, s->l1_table[i]);
                if (s->l1_table[i] > final_cluster)
@@ -907,41 +930,15 @@ int tdqcow_open (struct td_state *bs, co
        if(ret != 0) goto fail;
        s->cluster_cache_offset = -1;
 
-       /* read the backing file name */
-       s->bfd = -1;
-       if (header->backing_file_offset != 0) {
-               DPRINTF("Reading backing file data\n");
-               len = header->backing_file_size;
-               if (len > 1023)
-                       len = 1023;
-
-                /*TODO - Fix read size for O_DIRECT and use original fd!*/
-               fd = open(name, O_RDONLY | O_LARGEFILE);
-
-               lseek(fd, header->backing_file_offset, SEEK_SET);
-               if (read(fd, bs->backing_file, len) != len)
-                       goto fail;
-               bs->backing_file[len] = '\0';
-               close(fd);
-               /***********************************/
-
-               /*Open backing file*/
-               fd = open(bs->backing_file, O_RDONLY | O_DIRECT | O_LARGEFILE);
-               if (fd < 0) {
-                       DPRINTF("Unable to open backing file: %s\n",
-                               bs->backing_file);
-                       goto fail;
-               }
-               s->bfd = fd;
+       if (s->backing_file_offset != 0)
                s->cluster_alloc = 1; /*Cannot use pre-alloc*/
-       }
 
         bs->sector_size = 512;
         bs->info = 0;
        
        /*Detect min_cluster_alloc*/
        s->min_cluster_alloc = 1; /*Default*/
-       if (s->bfd == -1 && (s->l1_table_offset % 4096 == 0) ) {
+       if (s->backing_file_offset == 0 && s->l1_table_offset % 4096 == 0) {
                /*We test to see if the xen magic # exists*/
                exthdr = (QCowHeader_ext *)(buf + sizeof(QCowHeader));
                be32_to_cpus(&exthdr->xmagic);
@@ -962,10 +959,11 @@ int tdqcow_open (struct td_state *bs, co
        }
 
  end_xenhdr:
-       if (init_aio_state(bs)!=0) {
+       if (init_aio_state(dd)!=0) {
                DPRINTF("Unable to initialise AIO state\n");
                goto fail;
        }
+       init_fds(dd);
        s->fd_end = (final_cluster == 0 ? (s->l1_table_offset + l1_table_size) 
: 
                                (final_cluster + s->cluster_size));
 
@@ -981,213 +979,145 @@ fail:
        return -1;
 }
 
- int tdqcow_queue_read(struct td_state *bs, uint64_t sector,
-                              int nb_sectors, char *buf, td_callback_t cb,
-                              int id, void *private)
-{
-       struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
-       int ret = 0, index_in_cluster, n, i, qcow_idx, asubmit = 0;
-       uint64_t cluster_offset;
+int tdqcow_queue_read(struct disk_driver *dd, uint64_t sector,
+                     int nb_sectors, char *buf, td_callback_t cb,
+                     int id, void *private)
+{
+       struct tdqcow_state *s = (struct tdqcow_state *)dd->private;
+       int ret = 0, index_in_cluster, n, i, rsp = 0;
+       uint64_t cluster_offset, sec, nr_secs;
+
+       sec     = sector;
+       nr_secs = nb_sectors;
 
        /*Check we can get a lock*/
-       for (i = 0; i < nb_sectors; i++)
-               if (!aio_can_lock(s, sector + i)) {
-                       DPRINTF("AIO_CAN_LOCK failed [%llu]\n", 
-                               (long long) sector + i);
-                       return -EBUSY;
-               }
-       
+       for (i = 0; i < nb_sectors; i++) 
+               if (!aio_can_lock(s, sector + i)) 
+                       return cb(dd, -EBUSY, sector, nb_sectors, id, private);
+
        /*We store a local record of the request*/
-       qcow_idx = get_free_idx(s);
        while (nb_sectors > 0) {
                cluster_offset = 
-                       get_cluster_offset(bs, sector << 9, 0, 0, 0, 0);
+                       get_cluster_offset(s, sector << 9, 0, 0, 0, 0);
                index_in_cluster = sector & (s->cluster_sectors - 1);
                n = s->cluster_sectors - index_in_cluster;
                if (n > nb_sectors)
                        n = nb_sectors;
 
-               if (s->iocb_free_count == 0 || !aio_lock(s, sector)) {
-                       DPRINTF("AIO_LOCK or iocb_free_count (%d) failed" 
-                               "[%llu]\n", s->iocb_free_count, 
-                               (long long) sector);
-                       return -ENOMEM;
-               }
+               if (s->iocb_free_count == 0 || !aio_lock(s, sector)) 
+                       return cb(dd, -EBUSY, sector, nb_sectors, id, private);
                
-               if (!cluster_offset && (s->bfd > 0)) {
-                       s->nr_reqs[qcow_idx]++;
-                       asubmit += async_read(s, s->bfd, n * 512, sector << 9, 
-                                             buf, cb, id, sector, 
-                                             qcow_idx, private);
-               } else if(!cluster_offset) {
-                       memset(buf, 0, 512 * n);
+               if(!cluster_offset) {
                        aio_unlock(s, sector);
+                       ret = cb(dd, BLK_NOT_ALLOCATED, 
+                                sector, n, id, private);
+                       if (ret == -EBUSY) {
+                               /* mark remainder of request
+                                * as busy and try again later */
+                               return cb(dd, -EBUSY, sector + n,
+                                         nb_sectors - n, id, private);
+                       } else rsp += ret;
                } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
+                       aio_unlock(s, sector);
                        if (decompress_cluster(s, cluster_offset) < 0) {
-                               ret = -1;
+                               rsp += cb(dd, -EIO, sector, 
+                                         nb_sectors, id, private);
                                goto done;
                        }
                        memcpy(buf, s->cluster_cache + index_in_cluster * 512, 
                               512 * n);
-               } else {                        
-                       s->nr_reqs[qcow_idx]++;
-                       asubmit += async_read(s, s->fd, n * 512, 
-                                             (cluster_offset + 
-                                              index_in_cluster * 512), 
-                                             buf, cb, id, sector, 
-                                             qcow_idx, private);
+                       rsp += cb(dd, 0, sector, n, id, private);
+               } else {
+                       async_read(s, n * 512, 
+                                  (cluster_offset + index_in_cluster * 512),
+                                  buf, cb, id, sector, private);
                }
                nb_sectors -= n;
                sector += n;
                buf += n * 512;
        }
 done:
-        /*Callback if no async requests outstanding*/
-        if (!asubmit) return cb(bs, ret == -1 ? -1 : 0, id, private);
-
-       return 0;
-}
-
- int tdqcow_queue_write(struct td_state *bs, uint64_t sector,
-                              int nb_sectors, char *buf, td_callback_t cb,
-                              int id, void *private)
-{
-       struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
-       int ret = 0, index_in_cluster, n, i, qcow_idx, asubmit = 0;
-       uint64_t cluster_offset;
+       return rsp;
+}
+
+int tdqcow_queue_write(struct disk_driver *dd, uint64_t sector,
+                      int nb_sectors, char *buf, td_callback_t cb,
+                      int id, void *private)
+{
+       struct tdqcow_state *s = (struct tdqcow_state *)dd->private;
+       int ret = 0, index_in_cluster, n, i;
+       uint64_t cluster_offset, sec, nr_secs;
+
+       sec     = sector;
+       nr_secs = nb_sectors;
 
        /*Check we can get a lock*/
        for (i = 0; i < nb_sectors; i++)
-               if (!aio_can_lock(s, sector + i))  {
-                       DPRINTF("AIO_CAN_LOCK failed [%llu]\n", 
-                               (long long) (sector + i));
-                       return -EBUSY;
-               }
+               if (!aio_can_lock(s, sector + i))  
+                       return cb(dd, -EBUSY, sector, nb_sectors, id, private);
                   
        /*We store a local record of the request*/
-       qcow_idx = get_free_idx(s);     
        while (nb_sectors > 0) {
                index_in_cluster = sector & (s->cluster_sectors - 1);
                n = s->cluster_sectors - index_in_cluster;
                if (n > nb_sectors)
                        n = nb_sectors;
 
-               if (s->iocb_free_count == 0 || !aio_lock(s, sector)){
-                       DPRINTF("AIO_LOCK or iocb_free_count (%d) failed" 
-                               "[%llu]\n", s->iocb_free_count, 
-                               (long long) sector);
-                       return -ENOMEM;
-               }
-
-               if (!IS_ZERO(buf,n * 512)) {
-
-                       cluster_offset = get_cluster_offset(bs, sector << 9, 
-                                                           1, 0, 
-                                                           index_in_cluster, 
-                                                           index_in_cluster+n
-                               );
-                       if (!cluster_offset) {
-                               DPRINTF("Ooops, no write cluster offset!\n");
-                               ret = -1;
-                               goto done;
-                       }
-
-                       if (s->crypt_method) {
-                               encrypt_sectors(s, sector, s->cluster_data, 
-                                               (unsigned char *)buf, n, 1,
-                                               &s->aes_encrypt_key);
-                               s->nr_reqs[qcow_idx]++;
-                               asubmit += async_write(s, s->fd, n * 512, 
-                                                      (cluster_offset + 
-                                                       index_in_cluster*512), 
-                                                      (char *)s->cluster_data,
-                                                      cb, id, sector, 
-                                                      qcow_idx, private);
-                       } else {
-                               s->nr_reqs[qcow_idx]++;
-                               asubmit += async_write(s, s->fd, n * 512, 
-                                                      (cluster_offset + 
-                                                       index_in_cluster*512),
-                                                      buf, cb, id, sector, 
-                                                      qcow_idx, private);
-                       }
+               if (s->iocb_free_count == 0 || !aio_lock(s, sector))
+                       return cb(dd, -EBUSY, sector, nb_sectors, id, private);
+
+               cluster_offset = get_cluster_offset(s, sector << 9, 1, 0,
+                                                   index_in_cluster, 
+                                                   index_in_cluster+n);
+               if (!cluster_offset) {
+                       DPRINTF("Ooops, no write cluster offset!\n");
+                       return cb(dd, -EIO, sector, nb_sectors, id, private);
+               }
+
+               if (s->crypt_method) {
+                       encrypt_sectors(s, sector, s->cluster_data, 
+                                       (unsigned char *)buf, n, 1,
+                                       &s->aes_encrypt_key);
+                       async_write(s, n * 512, 
+                                   (cluster_offset + index_in_cluster*512),
+                                   (char *)s->cluster_data, cb, id, sector, 
+                                   private);
                } else {
-                       /*Write data contains zeros, but we must check to see 
-                         if cluster already allocated*/
-                       cluster_offset = get_cluster_offset(bs, sector << 9, 
-                                                           0, 0, 
-                                                           index_in_cluster, 
-                                                           index_in_cluster+n
-                               );      
-                       if(cluster_offset) {
-                               if (s->crypt_method) {
-                                       encrypt_sectors(s, sector, 
-                                                       s->cluster_data, 
-                                                       (unsigned char *)buf, 
-                                                       n, 1,
-                                                       &s->aes_encrypt_key);
-                                       s->nr_reqs[qcow_idx]++;
-                                       asubmit += async_write(s, s->fd, 
-                                                              n * 512, 
-                                                              (cluster_offset+
-                                                               
index_in_cluster * 512), 
-                                                              (char 
*)s->cluster_data, cb, id, sector, 
-                                                              qcow_idx, 
private);
-                               } else {
-                                       s->nr_reqs[qcow_idx]++;
-                                       asubmit += async_write(s, s->fd, n*512,
-                                                              cluster_offset + 
index_in_cluster * 512, 
-                                                              buf, cb, id, 
sector, 
-                                                              qcow_idx, 
private);
-                               }
-                       }
-                       else aio_unlock(s, sector);
-               }
+                       async_write(s, n * 512, 
+                                   (cluster_offset + index_in_cluster*512),
+                                   buf, cb, id, sector, private);
+               }
+               
                nb_sectors -= n;
                sector += n;
                buf += n * 512;
        }
        s->cluster_cache_offset = -1; /* disable compressed cache */
 
-done:
-       /*Callback if no async requests outstanding*/
-        if (!asubmit) return cb(bs, ret == -1 ? -1 : 0, id, private);
-
        return 0;
 }
                
-int tdqcow_submit(struct td_state *bs)
+int tdqcow_submit(struct disk_driver *dd)
 {
         int ret;
-        struct   tdqcow_state *prv = (struct tdqcow_state *)bs->private;
-
-        ret = io_submit(prv->aio_ctx, prv->iocb_queued, prv->iocb_queue);
+        struct   tdqcow_state *prv = (struct tdqcow_state *)dd->private;
+
+       if (!prv->iocb_queued)
+               return 0;
+
+       ret = io_submit(prv->aio_ctx, prv->iocb_queued, prv->iocb_queue);
 
         /* XXX: TODO: Handle error conditions here. */
 
         /* Success case: */
         prv->iocb_queued = 0;
 
-        return ret;
-}
-
-
-int *tdqcow_get_fd(struct td_state *bs)
-{
-       struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
-       int *fds, i;
-
-       fds = malloc(sizeof(int) * MAX_IOFD);
-       /*initialise the FD array*/
-       for(i=0;i<MAX_IOFD;i++) fds[i] = 0;
-
-       fds[0] = s->poll_fd;
-       return fds;
-}
-
-int tdqcow_close(struct td_state *bs)
-{
-       struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
+        return 0;
+}
+
+int tdqcow_close(struct disk_driver *dd)
+{
+       struct tdqcow_state *s = (struct tdqcow_state *)dd->private;
        uint32_t cksum, out;
        int fd, offset;
 
@@ -1203,6 +1133,7 @@ int tdqcow_close(struct td_state *bs)
                close(fd);
        }
 
+       io_destroy(s->aio_ctx);
        free(s->name);
        free(s->l1_table);
        free(s->l2_cache);
@@ -1212,11 +1143,11 @@ int tdqcow_close(struct td_state *bs)
        return 0;
 }
 
-int tdqcow_do_callbacks(struct td_state *s, int sid)
+int tdqcow_do_callbacks(struct disk_driver *dd, int sid)
 {
         int ret, i, rsp = 0,*ptr;
         struct io_event *ep;
-        struct tdqcow_state *prv = (struct tdqcow_state *)s->private;
+        struct tdqcow_state *prv = (struct tdqcow_state *)dd->private;
 
         if (sid > MAX_IOFD) return 1;
        
@@ -1224,25 +1155,24 @@ int tdqcow_do_callbacks(struct td_state 
         ret = io_getevents(prv->aio_ctx, 0, MAX_AIO_REQS, prv->aio_events,
                            NULL);
 
-        for (ep=prv->aio_events, i = ret; i-->0; ep++) {
+        for (ep = prv->aio_events, i = ret; i-- > 0; ep++) {
                 struct iocb        *io  = ep->obj;
                 struct pending_aio *pio;
 
                 pio = &prv->pending_aio[(long)io->data];
 
                aio_unlock(prv, pio->sector);
-               if (pio->id >= 0) {
-                       if (prv->crypt_method)
-                               encrypt_sectors(prv, pio->sector, 
-                                               (unsigned char *)pio->buf, 
-                                               (unsigned char *)pio->buf, 
-                                               pio->nb_sectors, 0, 
-                                               &prv->aes_decrypt_key);
-                       prv->nr_reqs[pio->qcow_idx]--;
-                       if (prv->nr_reqs[pio->qcow_idx] == 0) 
-                               rsp += pio->cb(s, ep->res == io->u.c.nbytes ? 0 
: 1, pio->id, 
-                                              pio->private);
-               } else if (pio->id == -2) free(pio->buf);
+
+               if (prv->crypt_method)
+                       encrypt_sectors(prv, pio->sector, 
+                                       (unsigned char *)pio->buf, 
+                                       (unsigned char *)pio->buf, 
+                                       pio->nb_sectors, 0, 
+                                       &prv->aes_decrypt_key);
+
+               rsp += pio->cb(dd, ep->res == io->u.c.nbytes ? 0 : 1, 
+                              pio->sector, pio->nb_sectors,
+                              pio->id, pio->private);
 
                 prv->iocb_free[prv->iocb_free_count++] = io;
         }
@@ -1250,7 +1180,7 @@ int tdqcow_do_callbacks(struct td_state 
 }
 
 int qcow_create(const char *filename, uint64_t total_size,
-                      const char *backing_file, int sparse)
+               const char *backing_file, int sparse)
 {
        int fd, header_size, backing_filename_len, l1_size, i;
        int shift, length, adjust, flags = 0, ret = 0;
@@ -1391,9 +1321,8 @@ int qcow_create(const char *filename, ui
        return 0;
 }
 
-int qcow_make_empty(struct td_state *bs)
-{
-       struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
+int qcow_make_empty(struct tdqcow_state *s)
+{
        uint32_t l1_length = s->l1_size * sizeof(uint64_t);
 
        memset(s->l1_table, 0, l1_length);
@@ -1412,19 +1341,16 @@ int qcow_make_empty(struct td_state *bs)
        return 0;
 }
 
-int qcow_get_cluster_size(struct td_state *bs)
-{
-       struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
-
+int qcow_get_cluster_size(struct tdqcow_state *s)
+{
        return s->cluster_size;
 }
 
 /* XXX: put compressed sectors first, then all the cluster aligned
    tables to avoid losing bytes in alignment */
-int qcow_compress_cluster(struct td_state *bs, int64_t sector_num, 
+int qcow_compress_cluster(struct tdqcow_state *s, int64_t sector_num, 
                           const uint8_t *buf)
 {
-       struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
        z_stream strm;
        int ret, out_len;
        uint8_t *out_buf;
@@ -1463,7 +1389,7 @@ int qcow_compress_cluster(struct td_stat
                /* could not compress: write normal cluster */
                //tdqcow_queue_write(bs, sector_num, buf, s->cluster_sectors);
        } else {
-               cluster_offset = get_cluster_offset(bs, sector_num << 9, 2, 
+               cluster_offset = get_cluster_offset(s, sector_num << 9, 2, 
                                             out_len, 0, 0);
                cluster_offset &= s->cluster_offset_mask;
                lseek(s->fd, cluster_offset, SEEK_SET);
@@ -1477,15 +1403,54 @@ int qcow_compress_cluster(struct td_stat
        return 0;
 }
 
+int tdqcow_has_parent(struct disk_driver *dd)
+{
+       struct tdqcow_state *s = (struct tdqcow_state *)dd->private;
+       return (s->backing_file_offset ? 1 : 0);
+}
+
+int tdqcow_get_parent(struct disk_driver *cdd, struct disk_driver *pdd)
+{
+       off_t off;
+       char *buf, *filename;
+       int len, secs, ret = -1;
+       struct tdqcow_state *child  = (struct tdqcow_state *)cdd->private;
+
+       if (!child->backing_file_offset)
+               return -1;
+
+       /* read the backing file name */
+       len  = child->backing_file_size;
+       off  = child->backing_file_offset - (child->backing_file_offset % 512);
+       secs = (len + (child->backing_file_offset - off) + 511) >> 9;
+
+       if (posix_memalign((void **)&buf, 512, secs << 9)) 
+               return -1;
+
+       if (lseek(child->fd, off, SEEK_SET) == (off_t)-1)
+               goto out;
+
+       if (read(child->fd, buf, secs << 9) != secs << 9)
+               goto out;
+       filename      = buf + (child->backing_file_offset - off);
+       filename[len] = '\0';
+
+       /*Open backing file*/
+       ret = tdqcow_open(pdd, filename);
+ out:
+       free(buf);
+       return ret;
+}
+
 struct tap_disk tapdisk_qcow = {
-       "tapdisk_qcow",
-       sizeof(struct tdqcow_state),
-       tdqcow_open,
-       tdqcow_queue_read,
-       tdqcow_queue_write,
-       tdqcow_submit,
-       tdqcow_get_fd,
-       tdqcow_close,
-       tdqcow_do_callbacks,
+       .disk_type           = "tapdisk_qcow",
+       .private_data_size   = sizeof(struct tdqcow_state),
+       .td_open             = tdqcow_open,
+       .td_queue_read       = tdqcow_queue_read,
+       .td_queue_write      = tdqcow_queue_write,
+       .td_submit           = tdqcow_submit,
+       .td_has_parent       = tdqcow_has_parent,
+       .td_get_parent       = tdqcow_get_parent,
+       .td_close            = tdqcow_close,
+       .td_do_callbacks     = tdqcow_do_callbacks,
 };
-
diff -r 04c23c1ef888 -r d907467f08cd tools/blktap/drivers/block-ram.c
--- a/tools/blktap/drivers/block-ram.c  Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/blktap/drivers/block-ram.c  Tue Feb 20 12:58:22 2007 -0700
@@ -123,14 +123,25 @@ static int get_image_info(struct td_stat
        return 0;
 }
 
+static inline void init_fds(struct disk_driver *dd)
+{
+        int i;
+       struct tdram_state *prv = (struct tdram_state *)dd->private;
+
+        for(i =0 ; i < MAX_IOFD; i++)
+               dd->io_fd[i] = 0;
+
+        dd->io_fd[0] = prv->poll_pipe[0];
+}
+
 /* Open the disk file and initialize ram state. */
-int tdram_open (struct td_state *s, const char *name)
-{
+int tdram_open (struct disk_driver *dd, const char *name)
+{
+       char *p;
+       uint64_t size;
        int i, fd, ret = 0, count = 0;
-       struct tdram_state *prv = (struct tdram_state *)s->private;
-       uint64_t size;
-       char *p;
-       s->private = prv;
+       struct td_state    *s     = dd->td_state;
+       struct tdram_state *prv   = (struct tdram_state *)dd->private;
 
        connections++;
        
@@ -209,88 +220,80 @@ int tdram_open (struct td_state *s, cons
                ret = 0;
        } 
 
+       init_fds(dd);
 done:
        return ret;
 }
 
- int tdram_queue_read(struct td_state *s, uint64_t sector,
-                              int nb_sectors, char *buf, td_callback_t cb,
-                              int id, void *private)
-{
-       struct tdram_state *prv = (struct tdram_state *)s->private;
+ int tdram_queue_read(struct disk_driver *dd, uint64_t sector,
+                     int nb_sectors, char *buf, td_callback_t cb,
+                     int id, void *private)
+{
+       struct td_state    *s   = dd->td_state;
+       struct tdram_state *prv = (struct tdram_state *)dd->private;
        int      size    = nb_sectors * s->sector_size;
        uint64_t offset  = sector * (uint64_t)s->sector_size;
-       int ret;
 
        memcpy(buf, img + offset, size);
-       ret = size;
-
-       cb(s, (ret < 0) ? ret: 0, id, private);
-
-       return ret;
-}
-
- int tdram_queue_write(struct td_state *s, uint64_t sector,
-                              int nb_sectors, char *buf, td_callback_t cb,
-                              int id, void *private)
-{
-       struct tdram_state *prv = (struct tdram_state *)s->private;
+
+       return cb(dd, 0, sector, nb_sectors, id, private);
+}
+
+int tdram_queue_write(struct disk_driver *dd, uint64_t sector,
+                     int nb_sectors, char *buf, td_callback_t cb,
+                     int id, void *private)
+{
+       struct td_state    *s   = dd->td_state;
+       struct tdram_state *prv = (struct tdram_state *)dd->private;
        int      size    = nb_sectors * s->sector_size;
        uint64_t offset  = sector * (uint64_t)s->sector_size;
-       int ret;
-       
-       /*We assume that write access is controlled at a higher level for 
multiple disks*/
+       
+       /* We assume that write access is controlled
+        * at a higher level for multiple disks */
        memcpy(img + offset, buf, size);
-       ret = size;
-
-       cb(s, (ret < 0) ? ret : 0, id, private);
-
-       return ret;
+
+       return cb(dd, 0, sector, nb_sectors, id, private);
 }
                
-int tdram_submit(struct td_state *s)
+int tdram_submit(struct disk_driver *dd)
 {
        return 0;       
 }
 
-
-int *tdram_get_fd(struct td_state *s)
-{
-       struct tdram_state *prv = (struct tdram_state *)s->private;
-        int *fds, i;
-
-        fds = malloc(sizeof(int) * MAX_IOFD);
-        /*initialise the FD array*/
-        for(i=0;i<MAX_IOFD;i++) fds[i] = 0;
-
-        fds[0] = prv->poll_pipe[0];
-        return fds;    
-}
-
-int tdram_close(struct td_state *s)
-{
-       struct tdram_state *prv = (struct tdram_state *)s->private;
+int tdram_close(struct disk_driver *dd)
+{
+       struct tdram_state *prv = (struct tdram_state *)dd->private;
        
        connections--;
        
        return 0;
 }
 
-int tdram_do_callbacks(struct td_state *s, int sid)
+int tdram_do_callbacks(struct disk_driver *dd, int sid)
 {
        /* always ask for a kick */
        return 1;
 }
 
+int tdram_has_parent(struct disk_driver *dd)
+{
+       return 0;
+}
+
+int tdram_get_parent(struct disk_driver *dd, struct disk_driver *parent)
+{
+       return -EINVAL;
+}
+
 struct tap_disk tapdisk_ram = {
-       "tapdisk_ram",
-       sizeof(struct tdram_state),
-       tdram_open,
-       tdram_queue_read,
-       tdram_queue_write,
-       tdram_submit,
-       tdram_get_fd,
-       tdram_close,
-       tdram_do_callbacks,
+       .disk_type          = "tapdisk_ram",
+       .private_data_size  = sizeof(struct tdram_state),
+       .td_open            = tdram_open,
+       .td_queue_read      = tdram_queue_read,
+       .td_queue_write     = tdram_queue_write,
+       .td_submit          = tdram_submit,
+       .td_has_parent      = tdram_has_parent,
+       .td_get_parent      = tdram_get_parent,
+       .td_close           = tdram_close,
+       .td_do_callbacks    = tdram_do_callbacks,
 };
-
diff -r 04c23c1ef888 -r d907467f08cd tools/blktap/drivers/block-sync.c
--- a/tools/blktap/drivers/block-sync.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/blktap/drivers/block-sync.c Tue Feb 20 12:58:22 2007 -0700
@@ -106,12 +106,23 @@ static int get_image_info(struct td_stat
        return 0;
 }
 
+static inline void init_fds(struct disk_driver *dd)
+{
+       int i;
+       struct tdsync_state *prv = (struct tdsync_state *)dd->private;
+       
+       for(i = 0; i < MAX_IOFD; i++)
+               dd->io_fd[i] = 0;
+
+       dd->io_fd[0] = prv->poll_pipe[0];
+}
+
 /* Open the disk file and initialize aio state. */
-int tdsync_open (struct td_state *s, const char *name)
+int tdsync_open (struct disk_driver *dd, const char *name)
 {
        int i, fd, ret = 0;
-       struct tdsync_state *prv = (struct tdsync_state *)s->private;
-       s->private = prv;
+       struct td_state     *s   = dd->td_state;
+       struct tdsync_state *prv = (struct tdsync_state *)dd->private;
        
        /* set up a pipe so that we can hand back a poll fd that won't fire.*/
        ret = pipe(prv->poll_pipe);
@@ -138,16 +149,18 @@ int tdsync_open (struct td_state *s, con
 
         prv->fd = fd;
 
+       init_fds(dd);
        ret = get_image_info(s, fd);
 done:
        return ret;     
 }
 
- int tdsync_queue_read(struct td_state *s, uint64_t sector,
+ int tdsync_queue_read(struct disk_driver *dd, uint64_t sector,
                               int nb_sectors, char *buf, td_callback_t cb,
                               int id, void *private)
 {
-       struct tdsync_state *prv = (struct tdsync_state *)s->private;
+       struct td_state     *s   = dd->td_state;
+       struct tdsync_state *prv = (struct tdsync_state *)dd->private;
        int      size    = nb_sectors * s->sector_size;
        uint64_t offset  = sector * (uint64_t)s->sector_size;
        int ret;
@@ -162,16 +175,15 @@ done:
                } 
        } else ret = 0 - errno;
                
-       cb(s, (ret < 0) ? ret: 0, id, private);
-       
-       return 1;
-}
-
- int tdsync_queue_write(struct td_state *s, uint64_t sector,
+       return cb(dd, (ret < 0) ? ret: 0, sector, nb_sectors, id, private);
+}
+
+ int tdsync_queue_write(struct disk_driver *dd, uint64_t sector,
                               int nb_sectors, char *buf, td_callback_t cb,
                               int id, void *private)
 {
-       struct tdsync_state *prv = (struct tdsync_state *)s->private;
+       struct td_state     *s   = dd->td_state;
+       struct tdsync_state *prv = (struct tdsync_state *)dd->private;
        int      size    = nb_sectors * s->sector_size;
        uint64_t offset  = sector * (uint64_t)s->sector_size;
        int ret = 0;
@@ -186,34 +198,17 @@ done:
                }
        } else ret = 0 - errno;
                
-       cb(s, (ret < 0) ? ret : 0, id, private);
-       
-       return 1;
+       return cb(dd, (ret < 0) ? ret : 0, sector, nb_sectors, id, private);
 }
                
-int tdsync_submit(struct td_state *s)
+int tdsync_submit(struct disk_driver *dd)
 {
        return 0;       
 }
 
-
-int *tdsync_get_fd(struct td_state *s)
-{
-       struct tdsync_state *prv = (struct tdsync_state *)s->private;
-       
-       int *fds, i;
-
-       fds = malloc(sizeof(int) * MAX_IOFD);
-       /*initialise the FD array*/
-       for(i=0;i<MAX_IOFD;i++) fds[i] = 0;
-
-       fds[0] = prv->poll_pipe[0];
-       return fds;
-}
-
-int tdsync_close(struct td_state *s)
-{
-       struct tdsync_state *prv = (struct tdsync_state *)s->private;
+int tdsync_close(struct disk_driver *dd)
+{
+       struct tdsync_state *prv = (struct tdsync_state *)dd->private;
        
        close(prv->fd);
        close(prv->poll_pipe[0]);
@@ -222,21 +217,31 @@ int tdsync_close(struct td_state *s)
        return 0;
 }
 
-int tdsync_do_callbacks(struct td_state *s, int sid)
+int tdsync_do_callbacks(struct disk_driver *dd, int sid)
 {
        /* always ask for a kick */
        return 1;
 }
 
+int tdsync_has_parent(struct disk_driver *dd)
+{
+       return 0;
+}
+
+int tdsync_get_parent(struct disk_driver *dd, struct disk_driver *parent)
+{
+       return -EINVAL;
+}
+
 struct tap_disk tapdisk_sync = {
-       "tapdisk_sync",
-       sizeof(struct tdsync_state),
-       tdsync_open,
-       tdsync_queue_read,
-       tdsync_queue_write,
-       tdsync_submit,
-       tdsync_get_fd,
-       tdsync_close,
-       tdsync_do_callbacks,
+       .disk_type           = "tapdisk_sync",
+       .private_data_size   = sizeof(struct tdsync_state),
+       .td_open             = tdsync_open,
+       .td_queue_read       = tdsync_queue_read,
+       .td_queue_write      = tdsync_queue_write,
+       .td_submit           = tdsync_submit,
+       .td_has_parent       = tdsync_has_parent,
+       .td_get_parent       = tdsync_get_parent,
+       .td_close            = tdsync_close,
+       .td_do_callbacks     = tdsync_do_callbacks,
 };
-
diff -r 04c23c1ef888 -r d907467f08cd tools/blktap/drivers/block-vmdk.c
--- a/tools/blktap/drivers/block-vmdk.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/blktap/drivers/block-vmdk.c Tue Feb 20 12:58:22 2007 -0700
@@ -107,14 +107,25 @@ struct tdvmdk_state {
        unsigned int cluster_sectors;
 };
 
+static inline void init_fds(struct disk_driver *dd)
+{
+        int i;
+       struct tdvmdk_state *prv = (struct tdvmdk_state *)dd->private;
+
+        for (i = 0; i < MAX_IOFD; i++)
+               dd->io_fd[i] = 0;
+
+        dd->io_fd[0] = prv->poll_pipe[0];
+}
 
 /* Open the disk file and initialize aio state. */
-static int tdvmdk_open (struct td_state *s, const char *name)
+static int tdvmdk_open (struct disk_driver *dd, const char *name)
 {
        int ret, fd;
        int l1_size, i;
        uint32_t magic;
-       struct tdvmdk_state *prv = (struct tdvmdk_state *)s->private;
+       struct td_state     *s   = dd->td_state;
+       struct tdvmdk_state *prv = (struct tdvmdk_state *)dd->private;
 
        /* set up a pipe so that we can hand back a poll fd that won't fire.*/
        ret = pipe(prv->poll_pipe);
@@ -206,6 +217,7 @@ static int tdvmdk_open (struct td_state 
        if (!prv->l2_cache)
                goto fail;
        prv->fd = fd;
+       init_fds(dd);
        DPRINTF("VMDK File opened successfully\n");
        return 0;
        
@@ -218,10 +230,9 @@ fail:
        return -1;
 }
 
-static uint64_t get_cluster_offset(struct td_state *s, 
+static uint64_t get_cluster_offset(struct tdvmdk_state *prv, 
                                    uint64_t offset, int allocate)
 {
-       struct tdvmdk_state *prv = (struct tdvmdk_state *)s->private;
        unsigned int l1_index, l2_offset, l2_index;
        int min_index, i, j;
        uint32_t min_count, *l2_table, tmp;
@@ -291,16 +302,17 @@ static uint64_t get_cluster_offset(struc
        return cluster_offset;
 }
 
-static int tdvmdk_queue_read(struct td_state *s, uint64_t sector,
+static int tdvmdk_queue_read(struct disk_driver *dd, uint64_t sector,
                               int nb_sectors, char *buf, td_callback_t cb,
                               int id, void *private)
 {
-       struct tdvmdk_state *prv = (struct tdvmdk_state *)s->private;
+       struct tdvmdk_state *prv = (struct tdvmdk_state *)dd->private;
        int index_in_cluster, n;
        uint64_t cluster_offset;
        int ret = 0;
+
        while (nb_sectors > 0) {
-               cluster_offset = get_cluster_offset(s, sector << 9, 0);
+               cluster_offset = get_cluster_offset(prv, sector << 9, 0);
                index_in_cluster = sector % prv->cluster_sectors;
                n = prv->cluster_sectors - index_in_cluster;
                if (n > nb_sectors)
@@ -321,27 +333,24 @@ static int tdvmdk_queue_read(struct td_s
                buf += n * 512;
        }
 done:
-       cb(s, ret == -1 ? -1 : 0, id, private);
-       
-       return 1;
-}
-
-static  int tdvmdk_queue_write(struct td_state *s, uint64_t sector,
+       return cb(dd, ret == -1 ? -1 : 0, sector, nb_sectors, id, private);
+}
+
+static  int tdvmdk_queue_write(struct disk_driver *dd, uint64_t sector,
                               int nb_sectors, char *buf, td_callback_t cb,
                               int id, void *private)
 {
-       struct tdvmdk_state *prv = (struct tdvmdk_state *)s->private;
+       struct tdvmdk_state *prv = (struct tdvmdk_state *)dd->private;
        int index_in_cluster, n;
        uint64_t cluster_offset;
        int ret = 0;
-       
 
        while (nb_sectors > 0) {
                index_in_cluster = sector & (prv->cluster_sectors - 1);
                n = prv->cluster_sectors - index_in_cluster;
                if (n > nb_sectors)
                        n = nb_sectors;
-               cluster_offset = get_cluster_offset(s, sector << 9, 1);
+               cluster_offset = get_cluster_offset(prv, sector << 9, 1);
                if (!cluster_offset) {
                        ret = -1;
                        goto done;
@@ -358,33 +367,17 @@ static  int tdvmdk_queue_write(struct td
                buf += n * 512;
        }
 done:
-       cb(s, ret == -1 ? -1 : 0, id, private);
-       
-       return 1;
+       return cb(dd, ret == -1 ? -1 : 0, sector, nb_sectors, id, private);
 }
                
-static int tdvmdk_submit(struct td_state *s)
+static int tdvmdk_submit(struct disk_driver *dd)
 {
        return 0;       
 }
 
-
-static int *tdvmdk_get_fd(struct td_state *s)
-{
-       struct tdvmdk_state *prv = (struct tdvmdk_state *)s->private;
-        int *fds, i;
-
-        fds = malloc(sizeof(int) * MAX_IOFD);
-        /*initialise the FD array*/
-        for (i=0;i<MAX_IOFD;i++) fds[i] = 0;
-
-        fds[0] = prv->poll_pipe[0];
-        return fds;
-}
-
-static int tdvmdk_close(struct td_state *s)
-{
-       struct tdvmdk_state *prv = (struct tdvmdk_state *)s->private;
+static int tdvmdk_close(struct disk_driver *dd)
+{
+       struct tdvmdk_state *prv = (struct tdvmdk_state *)dd->private;
        
        safer_free(prv->l1_table);
        safer_free(prv->l1_backup_table);
@@ -395,21 +388,31 @@ static int tdvmdk_close(struct td_state 
        return 0;
 }
 
-static int tdvmdk_do_callbacks(struct td_state *s, int sid)
+static int tdvmdk_do_callbacks(struct disk_driver *dd, int sid)
 {
        /* always ask for a kick */
        return 1;
 }
 
+static int tdvmdk_has_parent(struct disk_driver *dd)
+{
+       return 0;
+}
+
+static int tdvmdk_get_parent(struct disk_driver *dd, struct disk_driver 
*parent)
+{
+       return -EINVAL;
+}
+
 struct tap_disk tapdisk_vmdk = {
-       "tapdisk_vmdk",
-       sizeof(struct tdvmdk_state),
-       tdvmdk_open,
-       tdvmdk_queue_read,
-       tdvmdk_queue_write,
-       tdvmdk_submit,
-       tdvmdk_get_fd,
-       tdvmdk_close,
-       tdvmdk_do_callbacks,
+       .disk_type           = "tapdisk_vmdk",
+       .private_data_size   = sizeof(struct tdvmdk_state),
+       .td_open             = tdvmdk_open,
+       .td_queue_read       = tdvmdk_queue_read,
+       .td_queue_write      = tdvmdk_queue_write,
+       .td_submit           = tdvmdk_submit,
+       .td_has_parent       = tdvmdk_has_parent,
+       .td_get_parent       = tdvmdk_get_parent,
+       .td_close            = tdvmdk_close,
+       .td_do_callbacks     = tdvmdk_do_callbacks,
 };
-
diff -r 04c23c1ef888 -r d907467f08cd tools/blktap/drivers/img2qcow.c
--- a/tools/blktap/drivers/img2qcow.c   Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/blktap/drivers/img2qcow.c   Tue Feb 20 12:58:22 2007 -0700
@@ -147,7 +147,8 @@ static int get_image_info(struct td_stat
        return 0;
 }
 
-static int send_responses(struct td_state *s, int res, int idx, void *private)
+static int send_responses(struct disk_driver *dd, int res, uint64_t sec, 
+                         int nr_secs, int idx, void *private)
 {
        if (res < 0) DFPRINTF("AIO FAILURE: res [%d]!\n",res);
        
@@ -159,7 +160,7 @@ static int send_responses(struct td_stat
 
 int main(int argc, char *argv[])
 {
-       struct tap_disk *drv;
+       struct disk_driver dd;
        struct td_state *s;
        int ret = -1, fd, len;
        fd_set readfds;
@@ -195,16 +196,17 @@ int main(int argc, char *argv[])
        } else DFPRINTF("Qcow file created: size %llu sectors\n",
                        (long long unsigned)s->size);
        
-       drv = &tapdisk_qcow;
-       s->private = malloc(drv->private_data_size);
+       dd.td_state = s;
+       dd.drv      = &tapdisk_qcow;
+       dd.private  = malloc(dd.drv->private_data_size);
 
         /*Open qcow file*/
-        if (drv->td_open(s, argv[1])!=0) {
+        if (dd.drv->td_open(&dd, argv[1])!=0) {
                DFPRINTF("Unable to open Qcow file [%s]\n",argv[1]);
                exit(-1);
        }
 
-       io_fd = drv->td_get_fd(s);
+       io_fd = dd.io_fd;
 
        /*Initialise the output string*/
        memset(output,0x20,25);
@@ -245,9 +247,9 @@ int main(int argc, char *argv[])
                                len = (len >> 9) << 9;
                        }
 
-                       ret = drv->td_queue_write(s, i >> 9,
-                                                 len >> 9, buf, 
-                                                 send_responses, 0, buf);
+                       ret = dd.drv->td_queue_write(&dd, i >> 9,
+                                                    len >> 9, buf, 
+                                                    send_responses, 0, buf);
                                
                        if (!ret) submit_events++;
                                
@@ -261,7 +263,7 @@ int main(int argc, char *argv[])
                        debug_output(i,s->size << 9);
                        
                        if ((submit_events % 10 == 0) || complete) 
-                               drv->td_submit(s);
+                               dd.drv->td_submit(&dd);
                        timeout.tv_usec = 0;
                        
                } else {
@@ -275,14 +277,14 @@ int main(int argc, char *argv[])
                 ret = select(maxfds + 1, &readfds, (fd_set *) 0,
                              (fd_set *) 0, &timeout);
                             
-               if (ret > 0) drv->td_do_callbacks(s, 0);
+               if (ret > 0) dd.drv->td_do_callbacks(&dd, 0);
                if (complete && (returned_events == submit_events)) 
                        running = 0;
        }
        memcpy(output+prev+1,"=",1);
        DFPRINTF("\r%s     100%%\nTRANSFER COMPLETE\n\n", output);
-        drv->td_close(s);
-        free(s->private);
+        dd.drv->td_close(&dd);
+        free(dd.private);
         free(s);
                
        return 0;
diff -r 04c23c1ef888 -r d907467f08cd tools/blktap/drivers/qcow2raw.c
--- a/tools/blktap/drivers/qcow2raw.c   Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/blktap/drivers/qcow2raw.c   Tue Feb 20 12:58:22 2007 -0700
@@ -55,8 +55,7 @@ static int returned_read_events = 0, ret
 static int returned_read_events = 0, returned_write_events = 0;
 static int submit_events = 0;
 static uint32_t read_idx = 0, write_idx = 0;
-struct tap_disk *drv1, *drv2;
-struct td_state *sqcow, *saio;
+struct disk_driver ddqcow, ddaio;
 static uint64_t prev = 0, written = 0;
 static char output[25];
 
@@ -100,7 +99,8 @@ static inline void LOCAL_FD_SET(fd_set *
        return;
 }
 
-static int send_write_responses(struct td_state *s, int res, int idx, void 
*private)
+static int send_write_responses(struct disk_driver *dd, int res, uint64_t sec,
+                               int nr_secs, int idx, void *private)
 {
        if (res < 0) {
                DFPRINTF("AIO FAILURE: res [%d]!\n",res);
@@ -112,12 +112,13 @@ static int send_write_responses(struct t
        if (complete && (returned_write_events == submit_events)) 
                write_complete = 1;
 
-       debug_output(written, s->size << 9);
+       debug_output(written, dd->td_state->size << 9);
        free(private);
        return 0;
 }
 
-static int send_read_responses(struct td_state *s, int res, int idx, void 
*private)
+static int send_read_responses(struct disk_driver *dd, int res, uint64_t sec,
+                              int nr_secs, int idx, void *private)
 {
        int ret;
 
@@ -128,8 +129,8 @@ static int send_read_responses(struct td
        if (complete && (returned_read_events == submit_events)) 
                read_complete = 1;
        
-       ret = drv2->td_queue_write(saio, idx, BLOCK_PROCESSSZ>>9, private, 
-                                  send_write_responses, idx, private);
+       ret = ddaio.drv->td_queue_write(&ddaio, idx, BLOCK_PROCESSSZ>>9, 
private, 
+                                       send_write_responses, idx, private);
        if (ret != 0) {
                DFPRINTF("ERROR in submitting queue write!\n");
                return 0;
@@ -137,7 +138,7 @@ static int send_read_responses(struct td
 
        if ( (complete && returned_read_events == submit_events) || 
             (returned_read_events % 10 == 0) ) {
-               drv2->td_submit(saio);
+               ddaio.drv->td_submit(&ddaio);
        }
 
        return 0;
@@ -161,20 +162,20 @@ int main(int argc, char *argv[])
                exit(-1);
        }
 
-       sqcow = malloc(sizeof(struct td_state));
-       saio  = malloc(sizeof(struct td_state));
+       ddqcow.td_state = malloc(sizeof(struct td_state));
+       ddaio.td_state  = malloc(sizeof(struct td_state));
        
        /*Open qcow source file*/       
-       drv1 = &tapdisk_qcow;
-       sqcow->private = malloc(drv1->private_data_size);
-
-        if (drv1->td_open(sqcow, argv[2])!=0) {
+       ddqcow.drv = &tapdisk_qcow;
+       ddqcow.private = malloc(ddqcow.drv->private_data_size);
+
+        if (ddqcow.drv->td_open(&ddqcow, argv[2])!=0) {
                DFPRINTF("Unable to open Qcow file [%s]\n",argv[2]);
                exit(-1);
        } else DFPRINTF("QCOW file opened, size %llu\n",
-                     (long long unsigned)sqcow->size);
-
-       qcowio_fd = drv1->td_get_fd(sqcow);
+                     (long long unsigned)ddqcow.td_state->size);
+
+       qcowio_fd = ddqcow.io_fd;
 
         /*Setup aio destination file*/
        ret = stat(argv[1],&finfo);
@@ -191,12 +192,12 @@ int main(int argc, char *argv[])
                                       argv[1], 0 - errno);
                                exit(-1);
                        }
-                       if (ftruncate(fd, (off_t)sqcow->size<<9) < 0) {
+                       if (ftruncate(fd, (off_t)ddqcow.td_state->size<<9) < 0) 
{
                                DFPRINTF("Unable to create file "
                                        "[%s] of size %llu (errno %d). "
                                         "Exiting...\n",
                                        argv[1], 
-                                       (long long unsigned)sqcow->size<<9, 
+                                       (long long 
unsigned)ddqcow.td_state->size<<9, 
                                        0 - errno);
                                close(fd);
                                exit(-1);
@@ -238,43 +239,43 @@ int main(int argc, char *argv[])
                                close(fd);
                                exit(-1);
                        }
-                       if (size < sqcow->size<<9) {
+                       if (size < ddqcow.td_state->size<<9) {
                                DFPRINTF("ERROR: Not enough space on device "
                                        "%s (%lu bytes available, %llu bytes 
required\n",
                                        argv[1], size, 
-                                       (long long unsigned)sqcow->size<<9);
+                                       (long long 
unsigned)ddqcow.td_state->size<<9);
                                close(fd);
                                exit(-1);                               
                        }
                } else {
-                       if (ftruncate(fd, (off_t)sqcow->size<<9) < 0) {
+                       if (ftruncate(fd, (off_t)ddqcow.td_state->size<<9) < 0) 
{
                                DFPRINTF("Unable to create file "
                                        "[%s] of size %llu (errno %d). "
                                         "Exiting...\n",
                                        argv[1], 
-                                       (long long unsigned)sqcow->size<<9, 
+                                       (long long 
unsigned)ddqcow.td_state->size<<9, 
                                         0 - errno);
                                close(fd);
                                exit(-1);
                        } else DFPRINTF("File [%s] truncated to length %llu "
                                        "(%llu)\n", 
                                       argv[1], 
-                                      (long long unsigned)sqcow->size<<9, 
-                                      (long long unsigned)sqcow->size);
+                                      (long long 
unsigned)ddqcow.td_state->size<<9, 
+                                      (long long 
unsigned)ddqcow.td_state->size);
                }
                close(fd);
        }
 
        /*Open aio destination file*/   
-       drv2 = &tapdisk_aio;
-       saio->private = malloc(drv2->private_data_size);
-
-        if (drv2->td_open(saio, argv[1])!=0) {
+       ddaio.drv = &tapdisk_aio;
+       ddaio.private = malloc(ddaio.drv->private_data_size);
+
+        if (ddaio.drv->td_open(&ddaio, argv[1])!=0) {
                DFPRINTF("Unable to open Qcow file [%s]\n", argv[1]);
                exit(-1);
        }
 
-       aio_fd = drv2->td_get_fd(saio);
+       aio_fd = ddaio.io_fd;
 
        /*Initialise the output string*/
        memset(output,0x20,25);
@@ -298,9 +299,9 @@ int main(int argc, char *argv[])
                        }
                
                        /*Attempt to read 4k sized blocks*/
-                       ret = drv1->td_queue_read(sqcow, i>>9,
-                                                 BLOCK_PROCESSSZ>>9, buf, 
-                                                 send_read_responses, i>>9, 
buf);
+                       ret = ddqcow.drv->td_queue_read(&ddqcow, i>>9,
+                                                       BLOCK_PROCESSSZ>>9, 
buf, 
+                                                       send_read_responses, 
i>>9, buf);
 
                        if (ret < 0) {
                                DFPRINTF("UNABLE TO READ block [%llu]\n",
@@ -311,12 +312,12 @@ int main(int argc, char *argv[])
                                submit_events++;
                        }
 
-                       if (i >= sqcow->size<<9) {
+                       if (i >= ddqcow.td_state->size<<9) {
                                complete = 1;
                        }
                        
                        if ((submit_events % 10 == 0) || complete) 
-                               drv1->td_submit(sqcow);
+                               ddqcow.drv->td_submit(&ddqcow);
                        timeout.tv_usec = 0;
                        
                } else {
@@ -332,9 +333,9 @@ int main(int argc, char *argv[])
                             
                if (ret > 0) {
                        if (FD_ISSET(qcowio_fd[0], &readfds)) 
-                               drv1->td_do_callbacks(sqcow, 0);
+                               ddqcow.drv->td_do_callbacks(&ddqcow, 0);
                        if (FD_ISSET(aio_fd[0], &readfds)) 
-                               drv2->td_do_callbacks(saio, 0);
+                               ddaio.drv->td_do_callbacks(&ddaio, 0);
                }
                if (complete && (returned_write_events == submit_events)) 
                        running = 0;
diff -r 04c23c1ef888 -r d907467f08cd tools/blktap/drivers/tapdisk.c
--- a/tools/blktap/drivers/tapdisk.c    Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/blktap/drivers/tapdisk.c    Tue Feb 20 12:58:22 2007 -0700
@@ -48,6 +48,12 @@ int connected_disks = 0;
 int connected_disks = 0;
 fd_list_entry_t *fd_start = NULL;
 
+int do_cow_read(struct disk_driver *dd, blkif_request_t *req, 
+               int sidx, uint64_t sector, int nr_secs);
+
+#define td_for_each_disk(tds, drv) \
+        for (drv = tds->disks; drv != NULL; drv = drv->next)
+
 void usage(void) 
 {
        fprintf(stderr, "blktap-utils: v1.0.0\n");
@@ -78,10 +84,17 @@ static void unmap_disk(struct td_state *
 static void unmap_disk(struct td_state *s)
 {
        tapdev_info_t *info = s->ring_info;
-       struct tap_disk *drv = s->drv;
+       struct disk_driver *dd, *tmp;
        fd_list_entry_t *entry;
 
-       drv->td_close(s);
+       dd = s->disks;
+       while (dd) {
+               tmp = dd->next;
+               dd->drv->td_close(dd);
+               free(dd->private);
+               free(dd);
+               dd = tmp;
+       }
 
        if (info != NULL && info->mem > 0)
                munmap(info->mem, getpagesize() * BLKTAP_MMAP_REGION_SIZE);
@@ -96,7 +109,6 @@ static void unmap_disk(struct td_state *
        free(s->fd_entry);
        free(s->blkif);
        free(s->ring_info);
-        free(s->private);
        free(s);
 
        return;
@@ -113,16 +125,19 @@ static inline int LOCAL_FD_SET(fd_set *r
 static inline int LOCAL_FD_SET(fd_set *readfds)
 {
        fd_list_entry_t *ptr;
+       struct disk_driver *dd;
 
        ptr = fd_start;
        while (ptr != NULL) {
                if (ptr->tap_fd) {
                        FD_SET(ptr->tap_fd, readfds);
-                       if (ptr->io_fd[READ]) 
-                               FD_SET(ptr->io_fd[READ], readfds);
-                       maxfds = (ptr->io_fd[READ] > maxfds ? 
-                                       ptr->io_fd[READ]: maxfds);
-                       maxfds = (ptr->tap_fd > maxfds ? ptr->tap_fd: maxfds);
+                       td_for_each_disk(ptr->s, dd) {
+                               if (dd->io_fd[READ]) 
+                                       FD_SET(dd->io_fd[READ], readfds);
+                               maxfds = (dd->io_fd[READ] > maxfds ? 
+                                         dd->io_fd[READ] : maxfds);
+                       }
+                       maxfds = (ptr->tap_fd > maxfds ? ptr->tap_fd : maxfds);
                }
                ptr = ptr->next;
        }
@@ -130,8 +145,7 @@ static inline int LOCAL_FD_SET(fd_set *r
        return 0;
 }
 
-static inline fd_list_entry_t *add_fd_entry(
-       int tap_fd, int io_fd[MAX_IOFD], struct td_state *s)
+static inline fd_list_entry_t *add_fd_entry(int tap_fd, struct td_state *s)
 {
        fd_list_entry_t **pprev, *entry;
        int i;
@@ -139,12 +153,10 @@ static inline fd_list_entry_t *add_fd_en
        DPRINTF("Adding fd_list_entry\n");
 
        /*Add to linked list*/
-       s->fd_entry = entry = malloc(sizeof(fd_list_entry_t));
+       s->fd_entry   = entry = malloc(sizeof(fd_list_entry_t));
        entry->tap_fd = tap_fd;
-       for (i = 0; i < MAX_IOFD; i++)
-               entry->io_fd[i] = io_fd[i];
-       entry->s = s;
-       entry->next = NULL;
+       entry->s      = s;
+       entry->next   = NULL;
 
        pprev = &fd_start;
        while (*pprev != NULL)
@@ -171,7 +183,7 @@ static struct tap_disk *get_driver(int d
 static struct tap_disk *get_driver(int drivertype)
 {
        /* blktapctrl has passed us the driver type */
-       
+
        return dtypes[drivertype]->drv;
 }
 
@@ -183,12 +195,34 @@ static struct td_state *state_init(void)
 
        s = malloc(sizeof(struct td_state));
        blkif = s->blkif = malloc(sizeof(blkif_t));
-       s->ring_info = malloc(sizeof(tapdev_info_t));
-
-       for (i = 0; i < MAX_REQUESTS; i++)
-               blkif->pending_list[i].count = 0;
+       s->ring_info = calloc(1, sizeof(tapdev_info_t));
+
+       for (i = 0; i < MAX_REQUESTS; i++) {
+               blkif->pending_list[i].secs_pending = 0;
+               blkif->pending_list[i].submitting = 0;
+       }
 
        return s;
+}
+
+static struct disk_driver *disk_init(struct td_state *s, struct tap_disk *drv)
+{
+       struct disk_driver *dd;
+
+       dd = calloc(1, sizeof(struct disk_driver));
+       if (!dd)
+               return NULL;
+       
+       dd->private = malloc(drv->private_data_size);
+       if (!dd->private) {
+               free(dd);
+               return NULL;
+       }
+
+       dd->drv      = drv;
+       dd->td_state = s;
+
+       return dd;
 }
 
 static int map_new_dev(struct td_state *s, int minor)
@@ -246,6 +280,51 @@ static int map_new_dev(struct td_state *
        return -1;
 }
 
+static int open_disk(struct td_state *s, struct disk_driver *dd, char *path)
+{
+       int err;
+       struct disk_driver *d = dd;
+
+       err = dd->drv->td_open(dd, path);
+       if (err)
+               return err;
+
+       /* load backing files as necessary */
+       while (d->drv->td_has_parent(d)) {
+               struct disk_driver *new;
+               
+               new = calloc(1, sizeof(struct disk_driver));
+               if (!new)
+                       goto fail;
+               new->drv      = d->drv;
+               new->td_state = s;
+               new->private  = malloc(new->drv->private_data_size);
+               if (!new->private) {
+                       free(new);
+                       goto fail;
+               }
+               
+               err = d->drv->td_get_parent(d, new);
+               if (err)
+                       goto fail;
+
+               d = d->next = new;
+       }
+
+       return 0;
+
+ fail:
+       DPRINTF("failed opening disk\n");
+       while (dd) {
+               d = dd->next;
+               dd->drv->td_close(dd);
+               free(dd->private);
+               free(dd);
+               dd = d;
+       }
+       return err;
+}
+
 static int read_msg(char *buf)
 {
        int length, len, msglen, tap_fd, *io_fd;
@@ -255,6 +334,7 @@ static int read_msg(char *buf)
        msg_newdev_t *msg_dev;
        msg_pid_t *msg_pid;
        struct tap_disk *drv;
+       struct disk_driver *dd;
        int ret = -1;
        struct td_state *s = NULL;
        fd_list_entry_t *entry;
@@ -289,20 +369,20 @@ static int read_msg(char *buf)
                        if (s == NULL)
                                goto params_done;
 
-                       s->drv = drv;
-                       s->private = malloc(drv->private_data_size);
-                       if (s->private == NULL) {
+                       s->disks = dd = disk_init(s, drv);
+                       if (!dd) {
                                free(s);
                                goto params_done;
                        }
 
                        /*Open file*/
-                       ret = drv->td_open(s, path);
-                       io_fd = drv->td_get_fd(s);
-
-                       entry = add_fd_entry(0, io_fd, s);
+                       ret = open_disk(s, dd, path);
+                       if (ret)
+                               goto params_done;
+
+                       entry = add_fd_entry(0, s);
                        entry->cookie = msg->cookie;
-                       DPRINTF("Entered cookie %d\n",entry->cookie);
+                       DPRINTF("Entered cookie %d\n", entry->cookie);
                        
                        memset(buf, 0x00, MSG_SIZE); 
                        
@@ -323,13 +403,12 @@ static int read_msg(char *buf)
                        free(path);
                        return 1;
                        
-                       
-                       
                case CTLMSG_NEWDEV:
                        msg_dev = (msg_newdev_t *)(buf + sizeof(msg_hdr_t));
 
                        s = get_state(msg->cookie);
-                       DPRINTF("Retrieving state, cookie 
%d.....[%s]\n",msg->cookie, (s == NULL ? "FAIL":"OK"));
+                       DPRINTF("Retrieving state, cookie %d.....[%s]\n",
+                               msg->cookie, (s == NULL ? "FAIL":"OK"));
                        if (s != NULL) {
                                ret = ((map_new_dev(s, msg_dev->devnum) 
                                        == msg_dev->devnum ? 0: -1));
@@ -397,49 +476,75 @@ static inline void kick_responses(struct
        }
 }
 
-void io_done(struct td_state *s, int sid)
-{
-       struct tap_disk *drv = s->drv;
+void io_done(struct disk_driver *dd, int sid)
+{
+       struct tap_disk *drv = dd->drv;
 
        if (!run) return; /*We have received signal to close*/
 
-       if (drv->td_do_callbacks(s, sid) > 0) kick_responses(s);
+       if (drv->td_do_callbacks(dd, sid) > 0) kick_responses(dd->td_state);
 
        return;
 }
 
-int send_responses(struct td_state *s, int res, int idx, void *private)
-{
+static inline uint64_t
+segment_start(blkif_request_t *req, int sidx)
+{
+       int i;
+       uint64_t start = req->sector_number;
+
+       for (i = 0; i < sidx; i++) 
+               start += (req->seg[i].last_sect - req->seg[i].first_sect + 1);
+
+       return start;
+}
+
+uint64_t sends, responds;
+int send_responses(struct disk_driver *dd, int res, 
+                  uint64_t sector, int nr_secs, int idx, void *private)
+{
+       pending_req_t   *preq;
        blkif_request_t *req;
        int responses_queued = 0;
+       struct td_state *s = dd->td_state;
        blkif_t *blkif = s->blkif;
-
-       req   = &blkif->pending_list[idx].req;
-                       
-       if ( (idx > MAX_REQUESTS-1) || 
-           (blkif->pending_list[idx].count == 0) )
+       int sidx = (int)(long)private, secs_done = nr_secs;
+
+       if ( (idx > MAX_REQUESTS-1) )
        {
                DPRINTF("invalid index returned(%u)!\n", idx);
                return 0;
        }
+       preq = &blkif->pending_list[idx];
+       req  = &preq->req;
+
+       if (res == BLK_NOT_ALLOCATED) {
+               res = do_cow_read(dd, req, sidx, sector, nr_secs);
+               if (res >= 0) {
+                       secs_done = res;
+                       res = 0;
+               } else
+                       secs_done = 0;
+       }
+
+       preq->secs_pending -= secs_done;
+
+       if (res == -EBUSY && preq->submitting) 
+               return -EBUSY;  /* propagate -EBUSY back to higher layers */
+       if (res) 
+               preq->status = BLKIF_RSP_ERROR;
        
-       if (res != 0) {
-               blkif->pending_list[idx].status = BLKIF_RSP_ERROR;
-       }
-
-       blkif->pending_list[idx].count--;
-       
-       if (blkif->pending_list[idx].count == 0) 
+       if (!preq->submitting && preq->secs_pending == 0) 
        {
                blkif_request_t tmp;
                blkif_response_t *rsp;
-               
-               tmp = blkif->pending_list[idx].req;
+
+               tmp = preq->req;
                rsp = (blkif_response_t *)req;
                
                rsp->id = tmp.id;
                rsp->operation = tmp.operation;
-               rsp->status = blkif->pending_list[idx].status;
+               rsp->status = preq->status;
                
                write_rsp_to_ring(s, rsp);
                responses_queued++;
@@ -447,15 +552,51 @@ int send_responses(struct td_state *s, i
        return responses_queued;
 }
 
+int do_cow_read(struct disk_driver *dd, blkif_request_t *req, 
+               int sidx, uint64_t sector, int nr_secs)
+{
+       char *page;
+       int ret, early;
+       uint64_t seg_start, seg_end;
+       struct td_state  *s = dd->td_state;
+       tapdev_info_t *info = s->ring_info;
+       struct disk_driver *parent = dd->next;
+       
+       seg_start = segment_start(req, sidx);
+       seg_end   = seg_start + req->seg[sidx].last_sect + 1;
+       
+       ASSERT(sector >= seg_start && sector + nr_secs <= seg_end);
+
+       page  = (char *)MMAP_VADDR(info->vstart, 
+                                  (unsigned long)req->id, sidx);
+       page += (req->seg[sidx].first_sect << SECTOR_SHIFT);
+       page += ((sector - seg_start) << SECTOR_SHIFT);
+
+       if (!parent) {
+               memset(page, 0, nr_secs << SECTOR_SHIFT);
+               return nr_secs;
+       }
+
+       /* reissue request to backing file */
+       ret = parent->drv->td_queue_read(parent, sector, nr_secs,
+                                        page, send_responses, 
+                                        req->id, (void *)(long)sidx);
+       if (ret > 0)
+               parent->early += ret;
+
+       return ((ret >= 0) ? 0 : ret);
+}
+
 static void get_io_request(struct td_state *s)
 {
-       RING_IDX          rp, rc, j, i, ret;
+       RING_IDX          rp, rc, j, i;
        blkif_request_t  *req;
-       int idx, nsects;
+       int idx, nsects, ret;
        uint64_t sector_nr;
        char *page;
        int early = 0; /* count early completions */
-       struct tap_disk *drv = s->drv;
+       struct disk_driver *dd = s->disks;
+       struct tap_disk *drv   = dd->drv;
        blkif_t *blkif = s->blkif;
        tapdev_info_t *info = s->ring_info;
        int page_size = getpagesize();
@@ -466,23 +607,33 @@ static void get_io_request(struct td_sta
        rmb();
        for (j = info->fe_ring.req_cons; j != rp; j++)
        {
-               int done = 0; 
+               int done = 0, start_seg = 0; 
 
                req = NULL;
                req = RING_GET_REQUEST(&info->fe_ring, j);
                ++info->fe_ring.req_cons;
                
                if (req == NULL) continue;
-               
+
                idx = req->id;
-               ASSERT(blkif->pending_list[idx].count == 0);
-               memcpy(&blkif->pending_list[idx].req, req, sizeof(*req));
-               blkif->pending_list[idx].status = BLKIF_RSP_OKAY;
-               blkif->pending_list[idx].count = req->nr_segments;
-
-               sector_nr = req->sector_number;
-
-               for (i = 0; i < req->nr_segments; i++) {
+
+               if (info->busy.req) {
+                       /* continue where we left off last time */
+                       ASSERT(info->busy.req == req);
+                       start_seg = info->busy.seg_idx;
+                       sector_nr = segment_start(req, start_seg);
+                       info->busy.seg_idx = 0;
+                       info->busy.req     = NULL;
+               } else {
+                       ASSERT(blkif->pending_list[idx].secs_pending == 0);
+                       memcpy(&blkif->pending_list[idx].req, 
+                              req, sizeof(*req));
+                       blkif->pending_list[idx].status = BLKIF_RSP_OKAY;
+                       blkif->pending_list[idx].submitting = 1;
+                       sector_nr = req->sector_number;
+               }
+
+               for (i = start_seg; i < req->nr_segments; i++) {
                        nsects = req->seg[i].last_sect - 
                                 req->seg[i].first_sect + 1;
        
@@ -508,31 +659,37 @@ static void get_io_request(struct td_sta
                                        (long long unsigned) sector_nr);
                                continue;
                        }
-                       
+
+                       blkif->pending_list[idx].secs_pending += nsects;
+
                        switch (req->operation) 
                        {
                        case BLKIF_OP_WRITE:
-                               ret = drv->td_queue_write(s, sector_nr,
-                                               nsects, page, send_responses, 
-                                               idx, NULL);
-                               if (ret > 0) early += ret;
+                               ret = drv->td_queue_write(dd, sector_nr,
+                                                         nsects, page, 
+                                                         send_responses,
+                                                         idx, (void *)(long)i);
+                               if (ret > 0) dd->early += ret;
                                else if (ret == -EBUSY) {
-                                       /*
-                                        * TODO: Sector is locked         *
-                                        * Need to put req back on queue  *
-                                        */
+                                       /* put req back on queue */
+                                       --info->fe_ring.req_cons;
+                                       info->busy.req     = req;
+                                       info->busy.seg_idx = i;
+                                       goto out;
                                }
                                break;
                        case BLKIF_OP_READ:
-                               ret = drv->td_queue_read(s, sector_nr,
-                                               nsects, page, send_responses, 
-                                               idx, NULL);
-                               if (ret > 0) early += ret;
+                               ret = drv->td_queue_read(dd, sector_nr,
+                                                        nsects, page, 
+                                                        send_responses,
+                                                        idx, (void *)(long)i);
+                               if (ret > 0) dd->early += ret;
                                else if (ret == -EBUSY) {
-                                       /*
-                                        * TODO: Sector is locked         *
-                                        * Need to put req back on queue  *
-                                        */
+                                       /* put req back on queue */
+                                       --info->fe_ring.req_cons;
+                                       info->busy.req     = req;
+                                       info->busy.seg_idx = i;
+                                       goto out;
                                }
                                break;
                        default:
@@ -541,14 +698,22 @@ static void get_io_request(struct td_sta
                        }
                        sector_nr += nsects;
                }
-       }
-
+               blkif->pending_list[idx].submitting = 0;
+               /* force write_rsp_to_ring for synchronous case */
+               if (blkif->pending_list[idx].secs_pending == 0)
+                       dd->early += send_responses(dd, 0, 0, 0, idx, (void 
*)0);
+       }
+
+ out:
        /*Batch done*/
-       drv->td_submit(s);
-       
-       if (early > 0) 
-               io_done(s,10);
-               
+       td_for_each_disk(s, dd) {
+               dd->early += dd->drv->td_submit(dd);
+               if (dd->early > 0) {
+                       io_done(dd, 10);
+                       dd->early = 0;
+               }
+       }
+
        return;
 }
 
@@ -558,10 +723,9 @@ int main(int argc, char *argv[])
        char *p, *buf;
        fd_set readfds, writefds;       
        fd_list_entry_t *ptr;
-       struct tap_disk *drv;
        struct td_state *s;
        char openlogbuf[128];
-       
+
        if (argc != 3) usage();
 
        daemonize();
@@ -573,12 +737,12 @@ int main(int argc, char *argv[])
        signal (SIGINT, sig_handler);
 
        /*Open the control channel*/
-       fds[READ] = open(argv[1],O_RDWR|O_NONBLOCK);
+       fds[READ]  = open(argv[1],O_RDWR|O_NONBLOCK);
        fds[WRITE] = open(argv[2],O_RDWR|O_NONBLOCK);
 
        if ( (fds[READ] < 0) || (fds[WRITE] < 0) ) 
        {
-               DPRINTF("FD open failed [%d,%d]\n",fds[READ], fds[WRITE]);
+               DPRINTF("FD open failed [%d,%d]\n", fds[READ], fds[WRITE]);
                exit(-1);
        }
 
@@ -608,11 +772,22 @@ int main(int argc, char *argv[])
                {
                        ptr = fd_start;
                        while (ptr != NULL) {
-                               if (FD_ISSET(ptr->tap_fd, &readfds)) 
+                               int progress_made = 0;
+                               struct disk_driver *dd;
+                               tapdev_info_t *info = ptr->s->ring_info;
+
+                               td_for_each_disk(ptr->s, dd) {
+                                       if (dd->io_fd[READ] &&
+                                           FD_ISSET(dd->io_fd[READ], 
+                                                    &readfds)) {
+                                               io_done(dd, READ);
+                                               progress_made = 1;
+                                       }
+                               }
+
+                               if (FD_ISSET(ptr->tap_fd, &readfds) ||
+                                   (info->busy.req && progress_made))
                                        get_io_request(ptr->s);
-                               if (ptr->io_fd[READ] && 
-                                               FD_ISSET(ptr->io_fd[READ], 
&readfds)) 
-                                       io_done(ptr->s, READ);
 
                                ptr = ptr->next;
                        }
@@ -628,11 +803,8 @@ int main(int argc, char *argv[])
        ptr = fd_start;
        while (ptr != NULL) {
                s = ptr->s;
-               drv = s->drv;
 
                unmap_disk(s);
-               drv->td_close(s);
-               free(s->private);
                free(s->blkif);
                free(s->ring_info);
                free(s);
diff -r 04c23c1ef888 -r d907467f08cd tools/blktap/drivers/tapdisk.h
--- a/tools/blktap/drivers/tapdisk.h    Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/blktap/drivers/tapdisk.h    Tue Feb 20 12:58:22 2007 -0700
@@ -43,6 +43,9 @@
  *   - The fd used for poll is an otherwise unused pipe, which allows poll to 
  *     be safely called without ever returning anything.
  * 
+ * NOTE: tapdisk uses the number of sectors submitted per request as a 
+ * ref count.  Plugins must use the callback function to communicate the
+ * completion--or error--of every sector submitted to them.
  */
 
 #ifndef TAPDISK_H_
@@ -65,39 +68,55 @@
 #define SECTOR_SHIFT             9
 #define DEFAULT_SECTOR_SIZE    512
 
+#define MAX_IOFD                 2
+
+#define BLK_NOT_ALLOCATED       99
+
+struct td_state;
+struct tap_disk;
+
+struct disk_driver {
+       int early;
+       void *private;
+       int io_fd[MAX_IOFD];
+       struct tap_disk *drv;
+       struct td_state *td_state;
+       struct disk_driver *next;
+};
+
 /* This structure represents the state of an active virtual disk.           */
 struct td_state {
-       void *private;
-       void *drv;
+       struct disk_driver *disks;
        void *blkif;
        void *image;
        void *ring_info;
        void *fd_entry;
-       char backing_file[1024]; /*Used by differencing disks, e.g. qcow*/
        unsigned long      sector_size;
        unsigned long long size;
        unsigned int       info;
 };
 
 /* Prototype of the callback to activate as requests complete.              */
-typedef int (*td_callback_t)(struct td_state *s, int res, int id, void *prv);
+typedef int (*td_callback_t)(struct disk_driver *dd, int res, uint64_t sector,
+                            int nb_sectors, int id, void *private);
 
 /* Structure describing the interface to a virtual disk implementation.     */
 /* See note at the top of this file describing this interface.              */
 struct tap_disk {
        const char *disk_type;
        int private_data_size;
-       int (*td_open)        (struct td_state *s, const char *name);
-       int (*td_queue_read)  (struct td_state *s, uint64_t sector,
-                              int nb_sectors, char *buf, td_callback_t cb,
+       int (*td_open)        (struct disk_driver *dd, const char *name);
+       int (*td_queue_read)  (struct disk_driver *dd, uint64_t sector,
+                              int nb_sectors, char *buf, td_callback_t cb, 
                               int id, void *prv);
-       int (*td_queue_write) (struct td_state *s, uint64_t sector,
-                              int nb_sectors, char *buf, td_callback_t cb,
+       int (*td_queue_write) (struct disk_driver *dd, uint64_t sector,
+                              int nb_sectors, char *buf, td_callback_t cb, 
                               int id, void *prv);
-       int (*td_submit)      (struct td_state *s);
-       int *(*td_get_fd)      (struct td_state *s);
-       int (*td_close)       (struct td_state *s);
-       int (*td_do_callbacks)(struct td_state *s, int sid);
+       int (*td_submit)      (struct disk_driver *dd);
+       int (*td_has_parent)  (struct disk_driver *dd);
+       int (*td_get_parent)  (struct disk_driver *dd, struct disk_driver *p);
+       int (*td_close)       (struct disk_driver *dd);
+       int (*td_do_callbacks)(struct disk_driver *dd, int sid);
 };
 
 typedef struct disk_info {
@@ -119,14 +138,13 @@ extern struct tap_disk tapdisk_ram;
 extern struct tap_disk tapdisk_ram;
 extern struct tap_disk tapdisk_qcow;
 
-#define MAX_DISK_TYPES  20
-#define MAX_IOFD        2
-
-#define DISK_TYPE_AIO   0
-#define DISK_TYPE_SYNC  1
-#define DISK_TYPE_VMDK  2
-#define DISK_TYPE_RAM   3
-#define DISK_TYPE_QCOW  4
+#define MAX_DISK_TYPES     20
+
+#define DISK_TYPE_AIO      0
+#define DISK_TYPE_SYNC     1
+#define DISK_TYPE_VMDK     2
+#define DISK_TYPE_RAM      3
+#define DISK_TYPE_QCOW     4
 
 
 /*Define Individual Disk Parameters here */
@@ -197,12 +215,10 @@ typedef struct fd_list_entry {
 typedef struct fd_list_entry {
        int cookie;
        int  tap_fd;
-       int  io_fd[MAX_IOFD];
        struct td_state *s;
        struct fd_list_entry **pprev, *next;
 } fd_list_entry_t;
 
 int qcow_create(const char *filename, uint64_t total_size,
                const char *backing_file, int flags);
-
 #endif /*TAPDISK_H_*/
diff -r 04c23c1ef888 -r d907467f08cd tools/blktap/lib/blktaplib.h
--- a/tools/blktap/lib/blktaplib.h      Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/blktap/lib/blktaplib.h      Tue Feb 20 12:58:22 2007 -0700
@@ -91,8 +91,9 @@ struct blkif;
 
 typedef struct {
        blkif_request_t  req;
-       struct blkif         *blkif;
-       int              count;
+       struct blkif    *blkif;
+       int              submitting;
+       int              secs_pending;
         int16_t          status;
 } pending_req_t;
 
@@ -116,7 +117,7 @@ typedef struct blkif {
        
        void *prv;  /* device-specific data */
        void *info; /*Image parameter passing */
-       pending_req_t    pending_list[MAX_REQUESTS];
+       pending_req_t pending_list[MAX_REQUESTS];
        int devnum;
        int fds[2];
        int be_id;
@@ -141,6 +142,11 @@ void free_blkif(blkif_t *blkif);
 void free_blkif(blkif_t *blkif);
 void __init_blkif(void);
 
+typedef struct busy_state {
+       int seg_idx;
+       blkif_request_t *req;
+} busy_state_t;
+
 typedef struct tapdev_info {
        int fd;
        char *mem;
@@ -148,6 +154,7 @@ typedef struct tapdev_info {
        blkif_back_ring_t  fe_ring;
        unsigned long vstart;
        blkif_t *blkif;
+       busy_state_t busy;
 } tapdev_info_t;
 
 typedef struct domid_translate {
diff -r 04c23c1ef888 -r d907467f08cd tools/blktap/lib/xs_api.c
--- a/tools/blktap/lib/xs_api.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/blktap/lib/xs_api.c Tue Feb 20 12:58:22 2007 -0700
@@ -311,8 +311,8 @@ int unregister_xenbus_watch(struct xs_ha
        }
 
        if (!xs_unwatch(h, watch->node, token))
-               DPRINTF("XENBUS Failed to release watch %s: %i\n",
-                       watch->node, er);
+               DPRINTF("XENBUS Failed to release watch %s\n",
+                       watch->node);
 
        list_del(&watch->list);
        
@@ -351,9 +351,9 @@ int xs_fire_next_watch(struct xs_handle 
        
        node  = res[XS_WATCH_PATH];
        token = res[XS_WATCH_TOKEN];
-       
+
        w = find_watch(token);
-       if (w)
+       if (w) 
                w->callback(h, w, node);
 
        free(res);
diff -r 04c23c1ef888 -r d907467f08cd tools/check/check_zlib_lib
--- a/tools/check/check_zlib_lib        Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/check/check_zlib_lib        Tue Feb 20 12:58:22 2007 -0700
@@ -3,8 +3,10 @@
 
 RC=0
 
+PATH=/sbin:$PATH
+
 set -e
-ldconfig -v 2>&1 | grep -q libz.so || RC=1
+ldconfig -p 2>&1 | grep -q libz.so || RC=1
 
 if test ${RC} -ne 0; then
        echo
diff -r 04c23c1ef888 -r d907467f08cd tools/console/daemon/io.c
--- a/tools/console/daemon/io.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/console/daemon/io.c Tue Feb 20 12:58:22 2007 -0700
@@ -63,6 +63,7 @@ struct domain
        char *conspath;
        int ring_ref;
        evtchn_port_t local_port;
+       evtchn_port_t remote_port;
        int xce_handle;
        struct xencons_interface *interface;
 };
@@ -234,6 +235,9 @@ static int domain_create_ring(struct dom
        if (err)
                goto out;
 
+       if ((ring_ref == dom->ring_ref) && (remote_port == dom->remote_port))
+               goto out;
+
        if (ring_ref != dom->ring_ref) {
                if (dom->interface != NULL)
                        munmap(dom->interface, getpagesize());
@@ -249,6 +253,7 @@ static int domain_create_ring(struct dom
        }
 
        dom->local_port = -1;
+       dom->remote_port = -1;
        if (dom->xce_handle != -1)
                xc_evtchn_close(dom->xce_handle);
 
@@ -270,6 +275,7 @@ static int domain_create_ring(struct dom
                goto out;
        }
        dom->local_port = rc;
+       dom->remote_port = remote_port;
 
        if (dom->tty_fd == -1) {
                dom->tty_fd = domain_create_tty(dom);
@@ -279,6 +285,7 @@ static int domain_create_ring(struct dom
                        xc_evtchn_close(dom->xce_handle);
                        dom->xce_handle = -1;
                        dom->local_port = -1;
+                       dom->remote_port = -1;
                        goto out;
                }
        }
@@ -336,6 +343,7 @@ static struct domain *create_domain(int 
 
        dom->ring_ref = -1;
        dom->local_port = -1;
+       dom->remote_port = -1;
        dom->interface = NULL;
        dom->xce_handle = -1;
 
diff -r 04c23c1ef888 -r d907467f08cd tools/firmware/hvmloader/acpi/build.c
--- a/tools/firmware/hvmloader/acpi/build.c     Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/firmware/hvmloader/acpi/build.c     Tue Feb 20 12:58:22 2007 -0700
@@ -110,7 +110,9 @@ int construct_madt(struct acpi_20_madt *
         memset(lapic, 0, sizeof(*lapic));
         lapic->type    = ACPI_PROCESSOR_LOCAL_APIC;
         lapic->length  = sizeof(*lapic);
-        lapic->acpi_processor_id = lapic->apic_id = LAPIC_ID(i);
+        /* Processor ID must match processor-object IDs in the DSDT. */
+        lapic->acpi_processor_id = i;
+        lapic->apic_id = LAPIC_ID(i);
         lapic->flags   = ACPI_LOCAL_APIC_ENABLED;
         offset += sizeof(*lapic);
         lapic++;
@@ -144,6 +146,79 @@ int construct_hpet(struct acpi_20_hpet *
     return offset;
 }
 
+int construct_processor_objects(uint8_t *buf)
+{
+    static const char pdat[13] = { 0x5b, 0x83, 0x0b, 0x50, 0x52 };
+    static const char hex[] = "0123456789ABCDEF";
+    unsigned int i, length, nr_cpus = get_vcpu_nr();
+    struct acpi_header *hdr;
+    uint8_t *p = buf;
+
+    /*
+     * 1. Table Header.
+     */
+
+    hdr = (struct acpi_header *)p;
+    hdr->signature = ASCII32('S','S','D','T');
+    hdr->revision  = 2;
+    strncpy(hdr->oem_id, ACPI_OEM_ID, 6);
+    strncpy(hdr->oem_table_id, ACPI_OEM_TABLE_ID, 8);
+    hdr->oem_revision = ACPI_OEM_REVISION;
+    hdr->creator_id = ACPI_CREATOR_ID;
+    hdr->creator_revision = ACPI_CREATOR_REVISION;
+    p += sizeof(*hdr);
+
+    /*
+     * 2. Scope Definition.
+     */
+
+    /* ScopeOp */
+    *p++ = 0x10;
+
+    /* PkgLength (includes length bytes!). */
+    length = 1 + 5 + (nr_cpus * sizeof(pdat));
+    if ( length <= 0x3f )
+    {
+        *p++ = length;
+    }
+    else if ( ++length <= 0xfff )
+    {
+        *p++ = 0x40 | (length & 0xf);
+        *p++ = length >> 4;
+    }
+    else
+    {
+        length++;
+        *p++ = 0x80 | (length & 0xf);
+        *p++ = (length >>  4) & 0xff;
+        *p++ = (length >> 12) & 0xff;
+    }
+
+    /* NameString */
+    strncpy(p, "\\_PR_", 5);
+    p += 5;
+
+    /*
+     * 3. Processor Objects.
+     */
+
+    for ( i = 0; i < nr_cpus; i++ )
+    {
+        memcpy(p, pdat, sizeof(pdat));
+        /* ProcessorName */
+        p[5] = hex[(i>>4)&15];
+        p[6] = hex[(i>>0)&15];
+        /* ProcessorID */
+        p[7] = i;
+        p += sizeof(pdat);
+    }
+
+    hdr->length = p - buf;
+    set_checksum(hdr, offsetof(struct acpi_header, checksum), hdr->length);
+
+    return hdr->length;
+}
+
 int construct_secondary_tables(uint8_t *buf, unsigned long *table_ptrs)
 {
     int offset = 0, nr_tables = 0;
@@ -165,6 +240,10 @@ int construct_secondary_tables(uint8_t *
     hpet = (struct acpi_20_hpet *)&buf[offset];
     offset += construct_hpet(hpet);
     table_ptrs[nr_tables++] = (unsigned long)hpet;
+
+    /* Processor Object SSDT. */
+    table_ptrs[nr_tables++] = (unsigned long)&buf[offset];
+    offset += construct_processor_objects(&buf[offset]);
 
     /* TPM TCPA and SSDT. */
     tis_hdr = (uint16_t *)0xFED40F00;
diff -r 04c23c1ef888 -r d907467f08cd tools/firmware/hvmloader/acpi/dsdt.asl
--- a/tools/firmware/hvmloader/acpi/dsdt.asl    Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/firmware/hvmloader/acpi/dsdt.asl    Tue Feb 20 12:58:22 2007 -0700
@@ -27,14 +27,6 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, 
     Name (\APCL, 0x00010000)
     Name (\PUID, 0x00)
 
-    Scope (\_PR)
-    {
-        Processor (CPU0, 0x00, 0x00000000, 0x00) {}
-        Processor (CPU1, 0x01, 0x00000000, 0x00) {}
-        Processor (CPU2, 0x02, 0x00000000, 0x00) {}
-        Processor (CPU3, 0x03, 0x00000000, 0x00) {}
-    }
-
     /* Poweroff support - ties in with qemu emulation */
     Name (\_S5, Package (0x04)
     {
diff -r 04c23c1ef888 -r d907467f08cd tools/firmware/hvmloader/acpi/dsdt.c
--- a/tools/firmware/hvmloader/acpi/dsdt.c      Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/firmware/hvmloader/acpi/dsdt.c      Tue Feb 20 12:58:22 2007 -0700
@@ -1,19 +1,19 @@
 /*
  * 
  * Intel ACPI Component Architecture
- * ASL Optimizing Compiler version 20060707 [Dec 30 2006]
+ * ASL Optimizing Compiler version 20060707 [Feb 16 2007]
  * Copyright (C) 2000 - 2006 Intel Corporation
  * Supports ACPI Specification Revision 3.0a
  * 
- * Compilation of "dsdt.asl" - Sat Dec 30 15:31:23 2006
+ * Compilation of "dsdt.asl" - Fri Feb 16 15:14:37 2007
  * 
  * C source code output
  *
  */
 unsigned char AmlCode[] =
 {
-    0x44,0x53,0x44,0x54,0xD9,0x0D,0x00,0x00,  /* 00000000    "DSDT...." */
-    0x02,0xFB,0x58,0x65,0x6E,0x00,0x00,0x00,  /* 00000008    "..Xen..." */
+    0x44,0x53,0x44,0x54,0x9F,0x0D,0x00,0x00,  /* 00000000    "DSDT...." */
+    0x02,0xEE,0x58,0x65,0x6E,0x00,0x00,0x00,  /* 00000008    "..Xen..." */
     0x48,0x56,0x4D,0x00,0x00,0x00,0x00,0x00,  /* 00000010    "HVM....." */
     0x00,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C,  /* 00000018    "....INTL" */
     0x07,0x07,0x06,0x20,0x08,0x50,0x4D,0x42,  /* 00000020    "... .PMB" */
@@ -23,438 +23,430 @@ unsigned char AmlCode[] =
     0x41,0x50,0x43,0x42,0x0C,0x00,0x00,0xC0,  /* 00000040    "APCB...." */
     0xFE,0x08,0x41,0x50,0x43,0x4C,0x0C,0x00,  /* 00000048    "..APCL.." */
     0x00,0x01,0x00,0x08,0x50,0x55,0x49,0x44,  /* 00000050    "....PUID" */
-    0x00,0x10,0x39,0x5F,0x50,0x52,0x5F,0x5B,  /* 00000058    "..9_PR_[" */
-    0x83,0x0B,0x43,0x50,0x55,0x30,0x00,0x00,  /* 00000060    "..CPU0.." */
-    0x00,0x00,0x00,0x00,0x5B,0x83,0x0B,0x43,  /* 00000068    "....[..C" */
-    0x50,0x55,0x31,0x01,0x00,0x00,0x00,0x00,  /* 00000070    "PU1....." */
-    0x00,0x5B,0x83,0x0B,0x43,0x50,0x55,0x32,  /* 00000078    ".[..CPU2" */
-    0x02,0x00,0x00,0x00,0x00,0x00,0x5B,0x83,  /* 00000080    "......[." */
-    0x0B,0x43,0x50,0x55,0x33,0x03,0x00,0x00,  /* 00000088    ".CPU3..." */
-    0x00,0x00,0x00,0x08,0x5F,0x53,0x35,0x5F,  /* 00000090    "...._S5_" */
-    0x12,0x08,0x04,0x0A,0x07,0x0A,0x07,0x00,  /* 00000098    "........" */
-    0x00,0x08,0x50,0x49,0x43,0x44,0x00,0x14,  /* 000000A0    "..PICD.." */
-    0x0C,0x5F,0x50,0x49,0x43,0x01,0x70,0x68,  /* 000000A8    "._PIC.ph" */
-    0x50,0x49,0x43,0x44,0x10,0x44,0xD2,0x5F,  /* 000000B0    "PICD.D._" */
-    0x53,0x42,0x5F,0x5B,0x82,0x49,0x04,0x4D,  /* 000000B8    "SB_[.I.M" */
-    0x45,0x4D,0x30,0x08,0x5F,0x48,0x49,0x44,  /* 000000C0    "EM0._HID" */
-    0x0C,0x41,0xD0,0x0C,0x02,0x08,0x5F,0x43,  /* 000000C8    ".A...._C" */
-    0x52,0x53,0x11,0x33,0x0A,0x30,0x8A,0x2B,  /* 000000D0    "RS.3.0.+" */
-    0x00,0x00,0x0D,0x03,0x00,0x00,0x00,0x00,  /* 000000D8    "........" */
-    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000000E0    "........" */
-    0x00,0x00,0x00,0x00,0xFF,0xFF,0x09,0x00,  /* 000000E8    "........" */
-    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000000F0    "........" */
-    0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,  /* 000000F8    "........" */
-    0x00,0x00,0x00,0x00,0x79,0x00,0x5B,0x82,  /* 00000100    "....y.[." */
-    0x41,0xCD,0x50,0x43,0x49,0x30,0x08,0x5F,  /* 00000108    "A.PCI0._" */
-    0x48,0x49,0x44,0x0C,0x41,0xD0,0x0A,0x03,  /* 00000110    "HID.A..." */
-    0x08,0x5F,0x55,0x49,0x44,0x00,0x08,0x5F,  /* 00000118    "._UID.._" */
-    0x41,0x44,0x52,0x00,0x08,0x5F,0x42,0x42,  /* 00000120    "ADR.._BB" */
-    0x4E,0x00,0x14,0x44,0x08,0x5F,0x43,0x52,  /* 00000128    "N..D._CR" */
-    0x53,0x00,0x08,0x50,0x52,0x54,0x30,0x11,  /* 00000130    "S..PRT0." */
-    0x42,0x07,0x0A,0x6E,0x88,0x0D,0x00,0x02,  /* 00000138    "B..n...." */
-    0x0F,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,  /* 00000140    "........" */
-    0x00,0x00,0x00,0x01,0x47,0x01,0xF8,0x0C,  /* 00000148    "....G..." */
-    0xF8,0x0C,0x01,0x08,0x88,0x0D,0x00,0x01,  /* 00000150    "........" */
-    0x0C,0x03,0x00,0x00,0x00,0x00,0xF7,0x0C,  /* 00000158    "........" */
-    0x00,0x00,0xF8,0x0C,0x88,0x0D,0x00,0x01,  /* 00000160    "........" */
-    0x0C,0x03,0x00,0x00,0x00,0x0D,0xFF,0xFF,  /* 00000168    "........" */
-    0x00,0x00,0x00,0xF3,0x87,0x17,0x00,0x00,  /* 00000170    "........" */
-    0x0C,0x03,0x00,0x00,0x00,0x00,0x00,0x00,  /* 00000178    "........" */
-    0x0A,0x00,0xFF,0xFF,0x0B,0x00,0x00,0x00,  /* 00000180    "........" */
-    0x00,0x00,0x00,0x00,0x02,0x00,0x87,0x17,  /* 00000188    "........" */
-    0x00,0x00,0x0D,0x03,0x00,0x00,0x00,0x00,  /* 00000190    "........" */
-    0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0xF4,  /* 00000198    "........" */
-    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,  /* 000001A0    "........" */
-    0x79,0x00,0xA4,0x50,0x52,0x54,0x30,0x08,  /* 000001A8    "y..PRT0." */
-    0x42,0x55,0x46,0x41,0x11,0x09,0x0A,0x06,  /* 000001B0    "BUFA...." */
-    0x23,0x60,0x0C,0x18,0x79,0x00,0x08,0x42,  /* 000001B8    "#`..y..B" */
-    0x55,0x46,0x42,0x11,0x09,0x0A,0x06,0x23,  /* 000001C0    "UFB....#" */
-    0x00,0x00,0x18,0x79,0x00,0x8B,0x42,0x55,  /* 000001C8    "...y..BU" */
-    0x46,0x42,0x01,0x49,0x52,0x51,0x56,0x5B,  /* 000001D0    "FB.IRQV[" */
-    0x82,0x48,0x08,0x4C,0x4E,0x4B,0x41,0x08,  /* 000001D8    ".H.LNKA." */
-    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,  /* 000001E0    "_HID.A.." */
-    0x0F,0x08,0x5F,0x55,0x49,0x44,0x01,0x14,  /* 000001E8    ".._UID.." */
-    0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,  /* 000001F0    "._STA.{P" */
-    0x49,0x52,0x41,0x0A,0x80,0x60,0xA0,0x08,  /* 000001F8    "IRA..`.." */
-    0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,  /* 00000200    ".`......" */
-    0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,  /* 00000208    "......_P" */
-    0x52,0x53,0x00,0xA4,0x42,0x55,0x46,0x41,  /* 00000210    "RS..BUFA" */
-    0x14,0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,  /* 00000218    ".._DIS.}" */
-    0x50,0x49,0x52,0x41,0x0A,0x80,0x50,0x49,  /* 00000220    "PIRA..PI" */
-    0x52,0x41,0x14,0x1A,0x5F,0x43,0x52,0x53,  /* 00000228    "RA.._CRS" */
-    0x00,0x7B,0x50,0x49,0x52,0x41,0x0A,0x0F,  /* 00000230    ".{PIRA.." */
-    0x60,0x79,0x01,0x60,0x49,0x52,0x51,0x56,  /* 00000238    "`y.`IRQV" */
-    0xA4,0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,  /* 00000240    ".BUFB.._" */
-    0x53,0x52,0x53,0x01,0x8B,0x68,0x01,0x49,  /* 00000248    "SRS..h.I" */
-    0x52,0x51,0x31,0x82,0x49,0x52,0x51,0x31,  /* 00000250    "RQ1.IRQ1" */
-    0x60,0x76,0x60,0x70,0x60,0x50,0x49,0x52,  /* 00000258    "`v`p`PIR" */
-    0x41,0x5B,0x82,0x49,0x08,0x4C,0x4E,0x4B,  /* 00000260    "A[.I.LNK" */
-    0x42,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,  /* 00000268    "B._HID.A" */
-    0xD0,0x0C,0x0F,0x08,0x5F,0x55,0x49,0x44,  /* 00000270    "...._UID" */
-    0x0A,0x02,0x14,0x1C,0x5F,0x53,0x54,0x41,  /* 00000278    "...._STA" */
-    0x00,0x7B,0x50,0x49,0x52,0x42,0x0A,0x80,  /* 00000280    ".{PIRB.." */
-    0x60,0xA0,0x08,0x93,0x60,0x0A,0x80,0xA4,  /* 00000288    "`...`..." */
-    0x0A,0x09,0xA1,0x04,0xA4,0x0A,0x0B,0x14,  /* 00000290    "........" */
-    0x0B,0x5F,0x50,0x52,0x53,0x00,0xA4,0x42,  /* 00000298    "._PRS..B" */
-    0x55,0x46,0x41,0x14,0x11,0x5F,0x44,0x49,  /* 000002A0    "UFA.._DI" */
-    0x53,0x00,0x7D,0x50,0x49,0x52,0x42,0x0A,  /* 000002A8    "S.}PIRB." */
-    0x80,0x50,0x49,0x52,0x42,0x14,0x1A,0x5F,  /* 000002B0    ".PIRB.._" */
-    0x43,0x52,0x53,0x00,0x7B,0x50,0x49,0x52,  /* 000002B8    "CRS.{PIR" */
-    0x42,0x0A,0x0F,0x60,0x79,0x01,0x60,0x49,  /* 000002C0    "B..`y.`I" */
-    0x52,0x51,0x56,0xA4,0x42,0x55,0x46,0x42,  /* 000002C8    "RQV.BUFB" */
-    0x14,0x1B,0x5F,0x53,0x52,0x53,0x01,0x8B,  /* 000002D0    ".._SRS.." */
-    0x68,0x01,0x49,0x52,0x51,0x31,0x82,0x49,  /* 000002D8    "h.IRQ1.I" */
-    0x52,0x51,0x31,0x60,0x76,0x60,0x70,0x60,  /* 000002E0    "RQ1`v`p`" */
-    0x50,0x49,0x52,0x42,0x5B,0x82,0x49,0x08,  /* 000002E8    "PIRB[.I." */
-    0x4C,0x4E,0x4B,0x43,0x08,0x5F,0x48,0x49,  /* 000002F0    "LNKC._HI" */
-    0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F,  /* 000002F8    "D.A...._" */
-    0x55,0x49,0x44,0x0A,0x03,0x14,0x1C,0x5F,  /* 00000300    "UID...._" */
-    0x53,0x54,0x41,0x00,0x7B,0x50,0x49,0x52,  /* 00000308    "STA.{PIR" */
-    0x43,0x0A,0x80,0x60,0xA0,0x08,0x93,0x60,  /* 00000310    "C..`...`" */
-    0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04,0xA4,  /* 00000318    "........" */
-    0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52,0x53,  /* 00000320    "...._PRS" */
-    0x00,0xA4,0x42,0x55,0x46,0x41,0x14,0x11,  /* 00000328    "..BUFA.." */
-    0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,0x49,  /* 00000330    "_DIS.}PI" */
-    0x52,0x43,0x0A,0x80,0x50,0x49,0x52,0x43,  /* 00000338    "RC..PIRC" */
-    0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,0x7B,  /* 00000340    ".._CRS.{" */
-    0x50,0x49,0x52,0x43,0x0A,0x0F,0x60,0x79,  /* 00000348    "PIRC..`y" */
-    0x01,0x60,0x49,0x52,0x51,0x56,0xA4,0x42,  /* 00000350    ".`IRQV.B" */
-    0x55,0x46,0x42,0x14,0x1B,0x5F,0x53,0x52,  /* 00000358    "UFB.._SR" */
-    0x53,0x01,0x8B,0x68,0x01,0x49,0x52,0x51,  /* 00000360    "S..h.IRQ" */
-    0x31,0x82,0x49,0x52,0x51,0x31,0x60,0x76,  /* 00000368    "1.IRQ1`v" */
-    0x60,0x70,0x60,0x50,0x49,0x52,0x43,0x5B,  /* 00000370    "`p`PIRC[" */
-    0x82,0x49,0x08,0x4C,0x4E,0x4B,0x44,0x08,  /* 00000378    ".I.LNKD." */
-    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,  /* 00000380    "_HID.A.." */
-    0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A,0x04,  /* 00000388    ".._UID.." */
-    0x14,0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B,  /* 00000390    ".._STA.{" */
-    0x50,0x49,0x52,0x44,0x0A,0x80,0x60,0xA0,  /* 00000398    "PIRD..`." */
-    0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09,  /* 000003A0    "..`....." */
-    0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F,  /* 000003A8    "......._" */
-    0x50,0x52,0x53,0x00,0xA4,0x42,0x55,0x46,  /* 000003B0    "PRS..BUF" */
-    0x41,0x14,0x11,0x5F,0x44,0x49,0x53,0x00,  /* 000003B8    "A.._DIS." */
-    0x7D,0x50,0x49,0x52,0x44,0x0A,0x80,0x50,  /* 000003C0    "}PIRD..P" */
-    0x49,0x52,0x44,0x14,0x1A,0x5F,0x43,0x52,  /* 000003C8    "IRD.._CR" */
-    0x53,0x00,0x7B,0x50,0x49,0x52,0x44,0x0A,  /* 000003D0    "S.{PIRD." */
-    0x0F,0x60,0x79,0x01,0x60,0x49,0x52,0x51,  /* 000003D8    ".`y.`IRQ" */
-    0x56,0xA4,0x42,0x55,0x46,0x42,0x14,0x1B,  /* 000003E0    "V.BUFB.." */
-    0x5F,0x53,0x52,0x53,0x01,0x8B,0x68,0x01,  /* 000003E8    "_SRS..h." */
-    0x49,0x52,0x51,0x31,0x82,0x49,0x52,0x51,  /* 000003F0    "IRQ1.IRQ" */
-    0x31,0x60,0x76,0x60,0x70,0x60,0x50,0x49,  /* 000003F8    "1`v`p`PI" */
-    0x52,0x44,0x5B,0x82,0x3A,0x48,0x50,0x45,  /* 00000400    "RD[.:HPE" */
-    0x54,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,  /* 00000408    "T._HID.A" */
-    0xD0,0x01,0x03,0x08,0x5F,0x55,0x49,0x44,  /* 00000410    "...._UID" */
-    0x00,0x08,0x5F,0x43,0x52,0x53,0x11,0x1F,  /* 00000418    ".._CRS.." */
-    0x0A,0x1C,0x87,0x17,0x00,0x00,0x0D,0x01,  /* 00000420    "........" */
-    0x00,0x00,0x00,0x00,0x00,0x00,0xD0,0xFE,  /* 00000428    "........" */
-    0xFF,0x03,0xD0,0xFE,0x00,0x00,0x00,0x00,  /* 00000430    "........" */
-    0x00,0x04,0x00,0x00,0x79,0x00,0x14,0x16,  /* 00000438    "....y..." */
-    0x5F,0x50,0x52,0x54,0x00,0xA0,0x0A,0x50,  /* 00000440    "_PRT...P" */
-    0x49,0x43,0x44,0xA4,0x50,0x52,0x54,0x41,  /* 00000448    "ICD.PRTA" */
-    0xA4,0x50,0x52,0x54,0x50,0x08,0x50,0x52,  /* 00000450    ".PRTP.PR" */
-    0x54,0x50,0x12,0x49,0x36,0x3C,0x12,0x0D,  /* 00000458    "TP.I6<.." */
-    0x04,0x0C,0xFF,0xFF,0x01,0x00,0x00,0x4C,  /* 00000460    ".......L" */
-    0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,  /* 00000468    "NKB....." */
-    0xFF,0xFF,0x01,0x00,0x01,0x4C,0x4E,0x4B,  /* 00000470    ".....LNK" */
-    0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 00000478    "C......." */
-    0x01,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x44,  /* 00000480    "....LNKD" */
-    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x01,  /* 00000488    "........" */
-    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,0x00,  /* 00000490    "...LNKA." */
-    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x02,0x00,  /* 00000498    "........" */
-    0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,  /* 000004A0    ".LNKC..." */
-    0x04,0x0C,0xFF,0xFF,0x02,0x00,0x01,0x4C,  /* 000004A8    ".......L" */
-    0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C,  /* 000004B0    "NKD....." */
-    0xFF,0xFF,0x02,0x00,0x0A,0x02,0x4C,0x4E,  /* 000004B8    "......LN" */
-    0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 000004C0    "KA......" */
-    0xFF,0x02,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 000004C8    ".....LNK" */
-    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 000004D0    "B......." */
-    0x03,0x00,0x00,0x4C,0x4E,0x4B,0x44,0x00,  /* 000004D8    "...LNKD." */
-    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x03,0x00,  /* 000004E0    "........" */
-    0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E,  /* 000004E8    ".LNKA..." */
-    0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x02,  /* 000004F0    "........" */
-    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,  /* 000004F8    "LNKB...." */
-    0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x03,0x4C,  /* 00000500    ".......L" */
-    0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,  /* 00000508    "NKC....." */
-    0xFF,0xFF,0x04,0x00,0x00,0x4C,0x4E,0x4B,  /* 00000510    ".....LNK" */
-    0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000518    "A......." */
-    0x04,0x00,0x01,0x4C,0x4E,0x4B,0x42,0x00,  /* 00000520    "...LNKB." */
-    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x04,0x00,  /* 00000528    "........" */
-    0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 00000530    "..LNKC.." */
-    0x0E,0x04,0x0C,0xFF,0xFF,0x04,0x00,0x0A,  /* 00000538    "........" */
-    0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,  /* 00000540    ".LNKD..." */
-    0x04,0x0C,0xFF,0xFF,0x05,0x00,0x00,0x4C,  /* 00000548    ".......L" */
-    0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,  /* 00000550    "NKB....." */
-    0xFF,0xFF,0x05,0x00,0x01,0x4C,0x4E,0x4B,  /* 00000558    ".....LNK" */
-    0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 00000560    "C......." */
-    0x05,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x44,  /* 00000568    "....LNKD" */
-    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x05,  /* 00000570    "........" */
-    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,0x00,  /* 00000578    "...LNKA." */
-    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x06,0x00,  /* 00000580    "........" */
-    0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,  /* 00000588    ".LNKC..." */
-    0x04,0x0C,0xFF,0xFF,0x06,0x00,0x01,0x4C,  /* 00000590    ".......L" */
-    0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C,  /* 00000598    "NKD....." */
-    0xFF,0xFF,0x06,0x00,0x0A,0x02,0x4C,0x4E,  /* 000005A0    "......LN" */
-    0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 000005A8    "KA......" */
-    0xFF,0x06,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 000005B0    ".....LNK" */
-    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 000005B8    "B......." */
-    0x07,0x00,0x00,0x4C,0x4E,0x4B,0x44,0x00,  /* 000005C0    "...LNKD." */
-    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x07,0x00,  /* 000005C8    "........" */
-    0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E,  /* 000005D0    ".LNKA..." */
-    0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A,0x02,  /* 000005D8    "........" */
-    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,  /* 000005E0    "LNKB...." */
-    0x0C,0xFF,0xFF,0x07,0x00,0x0A,0x03,0x4C,  /* 000005E8    ".......L" */
-    0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,  /* 000005F0    "NKC....." */
-    0xFF,0xFF,0x08,0x00,0x00,0x4C,0x4E,0x4B,  /* 000005F8    ".....LNK" */
-    0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000600    "A......." */
-    0x08,0x00,0x01,0x4C,0x4E,0x4B,0x42,0x00,  /* 00000608    "...LNKB." */
-    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x08,0x00,  /* 00000610    "........" */
-    0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 00000618    "..LNKC.." */
-    0x0E,0x04,0x0C,0xFF,0xFF,0x08,0x00,0x0A,  /* 00000620    "........" */
-    0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,  /* 00000628    ".LNKD..." */
-    0x04,0x0C,0xFF,0xFF,0x09,0x00,0x00,0x4C,  /* 00000630    ".......L" */
-    0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,  /* 00000638    "NKB....." */
-    0xFF,0xFF,0x09,0x00,0x01,0x4C,0x4E,0x4B,  /* 00000640    ".....LNK" */
-    0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 00000648    "C......." */
-    0x09,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x44,  /* 00000650    "....LNKD" */
-    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x09,  /* 00000658    "........" */
-    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,0x00,  /* 00000660    "...LNKA." */
-    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0A,0x00,  /* 00000668    "........" */
-    0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,  /* 00000670    ".LNKC..." */
-    0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x01,0x4C,  /* 00000678    ".......L" */
-    0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C,  /* 00000680    "NKD....." */
-    0xFF,0xFF,0x0A,0x00,0x0A,0x02,0x4C,0x4E,  /* 00000688    "......LN" */
-    0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 00000690    "KA......" */
-    0xFF,0x0A,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 00000698    ".....LNK" */
-    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 000006A0    "B......." */
-    0x0B,0x00,0x00,0x4C,0x4E,0x4B,0x44,0x00,  /* 000006A8    "...LNKD." */
-    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0B,0x00,  /* 000006B0    "........" */
-    0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E,  /* 000006B8    ".LNKA..." */
-    0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A,0x02,  /* 000006C0    "........" */
-    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,  /* 000006C8    "LNKB...." */
-    0x0C,0xFF,0xFF,0x0B,0x00,0x0A,0x03,0x4C,  /* 000006D0    ".......L" */
-    0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,  /* 000006D8    "NKC....." */
-    0xFF,0xFF,0x0C,0x00,0x00,0x4C,0x4E,0x4B,  /* 000006E0    ".....LNK" */
-    0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 000006E8    "A......." */
-    0x0C,0x00,0x01,0x4C,0x4E,0x4B,0x42,0x00,  /* 000006F0    "...LNKB." */
-    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0C,0x00,  /* 000006F8    "........" */
-    0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 00000700    "..LNKC.." */
-    0x0E,0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x0A,  /* 00000708    "........" */
-    0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,  /* 00000710    ".LNKD..." */
-    0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x00,0x4C,  /* 00000718    ".......L" */
-    0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,  /* 00000720    "NKB....." */
-    0xFF,0xFF,0x0D,0x00,0x01,0x4C,0x4E,0x4B,  /* 00000728    ".....LNK" */
-    0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 00000730    "C......." */
-    0x0D,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x44,  /* 00000738    "....LNKD" */
-    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0D,  /* 00000740    "........" */
-    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,0x00,  /* 00000748    "...LNKA." */
-    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0E,0x00,  /* 00000750    "........" */
-    0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,  /* 00000758    ".LNKC..." */
-    0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x01,0x4C,  /* 00000760    ".......L" */
-    0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C,  /* 00000768    "NKD....." */
-    0xFF,0xFF,0x0E,0x00,0x0A,0x02,0x4C,0x4E,  /* 00000770    "......LN" */
-    0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 00000778    "KA......" */
-    0xFF,0x0E,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 00000780    ".....LNK" */
-    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000788    "B......." */
-    0x0F,0x00,0x00,0x4C,0x4E,0x4B,0x44,0x00,  /* 00000790    "...LNKD." */
-    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0F,0x00,  /* 00000798    "........" */
-    0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E,  /* 000007A0    ".LNKA..." */
-    0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A,0x02,  /* 000007A8    "........" */
-    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,  /* 000007B0    "LNKB...." */
-    0x0C,0xFF,0xFF,0x0F,0x00,0x0A,0x03,0x4C,  /* 000007B8    ".......L" */
-    0x4E,0x4B,0x43,0x00,0x08,0x50,0x52,0x54,  /* 000007C0    "NKC..PRT" */
-    0x41,0x12,0x41,0x2F,0x3C,0x12,0x0B,0x04,  /* 000007C8    "A.A/<..." */
-    0x0C,0xFF,0xFF,0x01,0x00,0x00,0x00,0x0A,  /* 000007D0    "........" */
-    0x14,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x01,  /* 000007D8    "........" */
-    0x00,0x01,0x00,0x0A,0x15,0x12,0x0C,0x04,  /* 000007E0    "........" */
-    0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x02,0x00,  /* 000007E8    "........" */
-    0x0A,0x16,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 000007F0    "........" */
-    0x01,0x00,0x0A,0x03,0x00,0x0A,0x17,0x12,  /* 000007F8    "........" */
-    0x0B,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x00,  /* 00000800    "........" */
-    0x00,0x0A,0x18,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000808    "........" */
-    0xFF,0x02,0x00,0x01,0x00,0x0A,0x19,0x12,  /* 00000810    "........" */
-    0x0C,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x0A,  /* 00000818    "........" */
-    0x02,0x00,0x0A,0x1A,0x12,0x0C,0x04,0x0C,  /* 00000820    "........" */
-    0xFF,0xFF,0x02,0x00,0x0A,0x03,0x00,0x0A,  /* 00000828    "........" */
-    0x1B,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x03,  /* 00000830    "........" */
-    0x00,0x00,0x00,0x0A,0x1C,0x12,0x0B,0x04,  /* 00000838    "........" */
-    0x0C,0xFF,0xFF,0x03,0x00,0x01,0x00,0x0A,  /* 00000840    "........" */
-    0x1D,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x03,  /* 00000848    "........" */
-    0x00,0x0A,0x02,0x00,0x0A,0x1E,0x12,0x0C,  /* 00000850    "........" */
-    0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x03,  /* 00000858    "........" */
-    0x00,0x0A,0x1F,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000860    "........" */
-    0xFF,0x04,0x00,0x00,0x00,0x0A,0x20,0x12,  /* 00000868    "...... ." */
-    0x0B,0x04,0x0C,0xFF,0xFF,0x04,0x00,0x01,  /* 00000870    "........" */
-    0x00,0x0A,0x21,0x12,0x0C,0x04,0x0C,0xFF,  /* 00000878    "..!....." */
-    0xFF,0x04,0x00,0x0A,0x02,0x00,0x0A,0x22,  /* 00000880    "......."" */
-    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x04,0x00,  /* 00000888    "........" */
-    0x0A,0x03,0x00,0x0A,0x23,0x12,0x0B,0x04,  /* 00000890    "....#..." */
-    0x0C,0xFF,0xFF,0x05,0x00,0x00,0x00,0x0A,  /* 00000898    "........" */
-    0x24,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x05,  /* 000008A0    "$......." */
-    0x00,0x01,0x00,0x0A,0x25,0x12,0x0C,0x04,  /* 000008A8    "....%..." */
-    0x0C,0xFF,0xFF,0x05,0x00,0x0A,0x02,0x00,  /* 000008B0    "........" */
-    0x0A,0x26,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 000008B8    ".&......" */
-    0x05,0x00,0x0A,0x03,0x00,0x0A,0x27,0x12,  /* 000008C0    "......'." */
-    0x0B,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x00,  /* 000008C8    "........" */
-    0x00,0x0A,0x28,0x12,0x0B,0x04,0x0C,0xFF,  /* 000008D0    "..(....." */
-    0xFF,0x06,0x00,0x01,0x00,0x0A,0x29,0x12,  /* 000008D8    "......)." */
-    0x0C,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x0A,  /* 000008E0    "........" */
-    0x02,0x00,0x0A,0x2A,0x12,0x0C,0x04,0x0C,  /* 000008E8    "...*...." */
-    0xFF,0xFF,0x06,0x00,0x0A,0x03,0x00,0x0A,  /* 000008F0    "........" */
-    0x2B,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x07,  /* 000008F8    "+......." */
-    0x00,0x00,0x00,0x0A,0x2C,0x12,0x0B,0x04,  /* 00000900    "....,..." */
-    0x0C,0xFF,0xFF,0x07,0x00,0x01,0x00,0x0A,  /* 00000908    "........" */
-    0x2D,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x07,  /* 00000910    "-......." */
-    0x00,0x0A,0x02,0x00,0x0A,0x2E,0x12,0x0C,  /* 00000918    "........" */
-    0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A,0x03,  /* 00000920    "........" */
-    0x00,0x0A,0x2F,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000928    "../....." */
-    0xFF,0x08,0x00,0x00,0x00,0x0A,0x11,0x12,  /* 00000930    "........" */
-    0x0B,0x04,0x0C,0xFF,0xFF,0x08,0x00,0x01,  /* 00000938    "........" */
-    0x00,0x0A,0x12,0x12,0x0C,0x04,0x0C,0xFF,  /* 00000940    "........" */
-    0xFF,0x08,0x00,0x0A,0x02,0x00,0x0A,0x13,  /* 00000948    "........" */
-    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x08,0x00,  /* 00000950    "........" */
-    0x0A,0x03,0x00,0x0A,0x14,0x12,0x0B,0x04,  /* 00000958    "........" */
-    0x0C,0xFF,0xFF,0x09,0x00,0x00,0x00,0x0A,  /* 00000960    "........" */
-    0x15,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x09,  /* 00000968    "........" */
-    0x00,0x01,0x00,0x0A,0x16,0x12,0x0C,0x04,  /* 00000970    "........" */
-    0x0C,0xFF,0xFF,0x09,0x00,0x0A,0x02,0x00,  /* 00000978    "........" */
-    0x0A,0x17,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000980    "........" */
-    0x09,0x00,0x0A,0x03,0x00,0x0A,0x18,0x12,  /* 00000988    "........" */
-    0x0B,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x00,  /* 00000990    "........" */
-    0x00,0x0A,0x19,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000998    "........" */
-    0xFF,0x0A,0x00,0x01,0x00,0x0A,0x1A,0x12,  /* 000009A0    "........" */
-    0x0C,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x0A,  /* 000009A8    "........" */
-    0x02,0x00,0x0A,0x1B,0x12,0x0C,0x04,0x0C,  /* 000009B0    "........" */
-    0xFF,0xFF,0x0A,0x00,0x0A,0x03,0x00,0x0A,  /* 000009B8    "........" */
-    0x1C,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0B,  /* 000009C0    "........" */
-    0x00,0x00,0x00,0x0A,0x1D,0x12,0x0B,0x04,  /* 000009C8    "........" */
-    0x0C,0xFF,0xFF,0x0B,0x00,0x01,0x00,0x0A,  /* 000009D0    "........" */
-    0x1E,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0B,  /* 000009D8    "........" */
-    0x00,0x0A,0x02,0x00,0x0A,0x1F,0x12,0x0C,  /* 000009E0    "........" */
-    0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A,0x03,  /* 000009E8    "........" */
-    0x00,0x0A,0x20,0x12,0x0B,0x04,0x0C,0xFF,  /* 000009F0    ".. ....." */
-    0xFF,0x0C,0x00,0x00,0x00,0x0A,0x21,0x12,  /* 000009F8    "......!." */
-    0x0B,0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x01,  /* 00000A00    "........" */
-    0x00,0x0A,0x22,0x12,0x0C,0x04,0x0C,0xFF,  /* 00000A08    ".."....." */
-    0xFF,0x0C,0x00,0x0A,0x02,0x00,0x0A,0x23,  /* 00000A10    ".......#" */
-    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0C,0x00,  /* 00000A18    "........" */
-    0x0A,0x03,0x00,0x0A,0x24,0x12,0x0B,0x04,  /* 00000A20    "....$..." */
-    0x0C,0xFF,0xFF,0x0D,0x00,0x00,0x00,0x0A,  /* 00000A28    "........" */
-    0x25,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0D,  /* 00000A30    "%......." */
-    0x00,0x01,0x00,0x0A,0x26,0x12,0x0C,0x04,  /* 00000A38    "....&..." */
-    0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x02,0x00,  /* 00000A40    "........" */
-    0x0A,0x27,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000A48    ".'......" */
-    0x0D,0x00,0x0A,0x03,0x00,0x0A,0x28,0x12,  /* 00000A50    "......(." */
-    0x0B,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x00,  /* 00000A58    "........" */
-    0x00,0x0A,0x29,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000A60    "..)....." */
-    0xFF,0x0E,0x00,0x01,0x00,0x0A,0x2A,0x12,  /* 00000A68    "......*." */
-    0x0C,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x0A,  /* 00000A70    "........" */
-    0x02,0x00,0x0A,0x2B,0x12,0x0C,0x04,0x0C,  /* 00000A78    "...+...." */
-    0xFF,0xFF,0x0E,0x00,0x0A,0x03,0x00,0x0A,  /* 00000A80    "........" */
-    0x2C,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0F,  /* 00000A88    ",......." */
-    0x00,0x00,0x00,0x0A,0x2D,0x12,0x0B,0x04,  /* 00000A90    "....-..." */
-    0x0C,0xFF,0xFF,0x0F,0x00,0x01,0x00,0x0A,  /* 00000A98    "........" */
-    0x2E,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0F,  /* 00000AA0    "........" */
-    0x00,0x0A,0x02,0x00,0x0A,0x2F,0x12,0x0C,  /* 00000AA8    "...../.." */
-    0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A,0x03,  /* 00000AB0    "........" */
-    0x00,0x0A,0x10,0x5B,0x82,0x4C,0x31,0x49,  /* 00000AB8    "...[.L1I" */
-    0x53,0x41,0x5F,0x08,0x5F,0x41,0x44,0x52,  /* 00000AC0    "SA_._ADR" */
-    0x0C,0x00,0x00,0x01,0x00,0x5B,0x80,0x50,  /* 00000AC8    ".....[.P" */
-    0x49,0x52,0x51,0x02,0x0A,0x60,0x0A,0x04,  /* 00000AD0    "IRQ..`.." */
-    0x10,0x2E,0x5C,0x00,0x5B,0x81,0x29,0x5C,  /* 00000AD8    "..\.[.)\" */
-    0x2F,0x04,0x5F,0x53,0x42,0x5F,0x50,0x43,  /* 00000AE0    "/._SB_PC" */
-    0x49,0x30,0x49,0x53,0x41,0x5F,0x50,0x49,  /* 00000AE8    "I0ISA_PI" */
-    0x52,0x51,0x01,0x50,0x49,0x52,0x41,0x08,  /* 00000AF0    "RQ.PIRA." */
-    0x50,0x49,0x52,0x42,0x08,0x50,0x49,0x52,  /* 00000AF8    "PIRB.PIR" */
-    0x43,0x08,0x50,0x49,0x52,0x44,0x08,0x5B,  /* 00000B00    "C.PIRD.[" */
-    0x82,0x46,0x0B,0x53,0x59,0x53,0x52,0x08,  /* 00000B08    ".F.SYSR." */
-    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,  /* 00000B10    "_HID.A.." */
-    0x02,0x08,0x5F,0x55,0x49,0x44,0x01,0x08,  /* 00000B18    ".._UID.." */
-    0x43,0x52,0x53,0x5F,0x11,0x4E,0x08,0x0A,  /* 00000B20    "CRS_.N.." */
-    0x8A,0x47,0x01,0x10,0x00,0x10,0x00,0x00,  /* 00000B28    ".G......" */
-    0x10,0x47,0x01,0x22,0x00,0x22,0x00,0x00,  /* 00000B30    ".G.".".." */
-    0x0C,0x47,0x01,0x30,0x00,0x30,0x00,0x00,  /* 00000B38    ".G.0.0.." */
-    0x10,0x47,0x01,0x44,0x00,0x44,0x00,0x00,  /* 00000B40    ".G.D.D.." */
-    0x1C,0x47,0x01,0x62,0x00,0x62,0x00,0x00,  /* 00000B48    ".G.b.b.." */
-    0x02,0x47,0x01,0x65,0x00,0x65,0x00,0x00,  /* 00000B50    ".G.e.e.." */
-    0x0B,0x47,0x01,0x72,0x00,0x72,0x00,0x00,  /* 00000B58    ".G.r.r.." */
-    0x0E,0x47,0x01,0x80,0x00,0x80,0x00,0x00,  /* 00000B60    ".G......" */
-    0x01,0x47,0x01,0x84,0x00,0x84,0x00,0x00,  /* 00000B68    ".G......" */
-    0x03,0x47,0x01,0x88,0x00,0x88,0x00,0x00,  /* 00000B70    ".G......" */
-    0x01,0x47,0x01,0x8C,0x00,0x8C,0x00,0x00,  /* 00000B78    ".G......" */
-    0x03,0x47,0x01,0x90,0x00,0x90,0x00,0x00,  /* 00000B80    ".G......" */
-    0x10,0x47,0x01,0xA2,0x00,0xA2,0x00,0x00,  /* 00000B88    ".G......" */
-    0x1C,0x47,0x01,0xE0,0x00,0xE0,0x00,0x00,  /* 00000B90    ".G......" */
-    0x10,0x47,0x01,0xA0,0x08,0xA0,0x08,0x00,  /* 00000B98    ".G......" */
-    0x04,0x47,0x01,0xC0,0x0C,0xC0,0x0C,0x00,  /* 00000BA0    ".G......" */
-    0x10,0x47,0x01,0xD0,0x04,0xD0,0x04,0x00,  /* 00000BA8    ".G......" */
-    0x02,0x79,0x00,0x14,0x0B,0x5F,0x43,0x52,  /* 00000BB0    ".y..._CR" */
-    0x53,0x00,0xA4,0x43,0x52,0x53,0x5F,0x5B,  /* 00000BB8    "S..CRS_[" */
-    0x82,0x2B,0x50,0x49,0x43,0x5F,0x08,0x5F,  /* 00000BC0    ".+PIC_._" */
-    0x48,0x49,0x44,0x0B,0x41,0xD0,0x08,0x5F,  /* 00000BC8    "HID.A.._" */
-    0x43,0x52,0x53,0x11,0x18,0x0A,0x15,0x47,  /* 00000BD0    "CRS....G" */
-    0x01,0x20,0x00,0x20,0x00,0x01,0x02,0x47,  /* 00000BD8    ". . ...G" */
-    0x01,0xA0,0x00,0xA0,0x00,0x01,0x02,0x22,  /* 00000BE0    "......."" */
-    0x04,0x00,0x79,0x00,0x5B,0x82,0x47,0x05,  /* 00000BE8    "..y.[.G." */
-    0x44,0x4D,0x41,0x30,0x08,0x5F,0x48,0x49,  /* 00000BF0    "DMA0._HI" */
-    0x44,0x0C,0x41,0xD0,0x02,0x00,0x08,0x5F,  /* 00000BF8    "D.A...._" */
-    0x43,0x52,0x53,0x11,0x41,0x04,0x0A,0x3D,  /* 00000C00    "CRS.A..=" */
-    0x2A,0x10,0x04,0x47,0x01,0x00,0x00,0x00,  /* 00000C08    "*..G...." */
-    0x00,0x00,0x10,0x47,0x01,0x81,0x00,0x81,  /* 00000C10    "...G...." */
-    0x00,0x00,0x03,0x47,0x01,0x87,0x00,0x87,  /* 00000C18    "...G...." */
-    0x00,0x00,0x01,0x47,0x01,0x89,0x00,0x89,  /* 00000C20    "...G...." */
-    0x00,0x00,0x03,0x47,0x01,0x8F,0x00,0x8F,  /* 00000C28    "...G...." */
-    0x00,0x00,0x01,0x47,0x01,0xC0,0x00,0xC0,  /* 00000C30    "...G...." */
-    0x00,0x00,0x20,0x47,0x01,0x80,0x04,0x80,  /* 00000C38    ".. G...." */
-    0x04,0x00,0x10,0x79,0x00,0x5B,0x82,0x25,  /* 00000C40    "...y.[.%" */
-    0x54,0x4D,0x52,0x5F,0x08,0x5F,0x48,0x49,  /* 00000C48    "TMR_._HI" */
-    0x44,0x0C,0x41,0xD0,0x01,0x00,0x08,0x5F,  /* 00000C50    "D.A...._" */
-    0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,  /* 00000C58    "CRS....G" */
-    0x01,0x40,0x00,0x40,0x00,0x00,0x04,0x22,  /* 00000C60    ".@.@..."" */
-    0x01,0x00,0x79,0x00,0x5B,0x82,0x25,0x52,  /* 00000C68    "..y.[.%R" */
-    0x54,0x43,0x5F,0x08,0x5F,0x48,0x49,0x44,  /* 00000C70    "TC_._HID" */
-    0x0C,0x41,0xD0,0x0B,0x00,0x08,0x5F,0x43,  /* 00000C78    ".A...._C" */
-    0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,0x01,  /* 00000C80    "RS....G." */
-    0x70,0x00,0x70,0x00,0x00,0x02,0x22,0x00,  /* 00000C88    "p.p..."." */
-    0x01,0x79,0x00,0x5B,0x82,0x22,0x53,0x50,  /* 00000C90    ".y.[."SP" */
-    0x4B,0x52,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 00000C98    "KR._HID." */
-    0x41,0xD0,0x08,0x00,0x08,0x5F,0x43,0x52,  /* 00000CA0    "A...._CR" */
-    0x53,0x11,0x0D,0x0A,0x0A,0x47,0x01,0x61,  /* 00000CA8    "S....G.a" */
-    0x00,0x61,0x00,0x00,0x01,0x79,0x00,0x5B,  /* 00000CB0    ".a...y.[" */
-    0x82,0x31,0x50,0x53,0x32,0x4D,0x08,0x5F,  /* 00000CB8    ".1PS2M._" */
-    0x48,0x49,0x44,0x0C,0x41,0xD0,0x0F,0x13,  /* 00000CC0    "HID.A..." */
-    0x08,0x5F,0x43,0x49,0x44,0x0C,0x41,0xD0,  /* 00000CC8    "._CID.A." */
-    0x0F,0x13,0x14,0x09,0x5F,0x53,0x54,0x41,  /* 00000CD0    "...._STA" */
-    0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52,  /* 00000CD8    "....._CR" */
-    0x53,0x11,0x08,0x0A,0x05,0x22,0x00,0x10,  /* 00000CE0    "S....".." */
-    0x79,0x00,0x5B,0x82,0x42,0x04,0x50,0x53,  /* 00000CE8    "y.[.B.PS" */
-    0x32,0x4B,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 00000CF0    "2K._HID." */
-    0x41,0xD0,0x03,0x03,0x08,0x5F,0x43,0x49,  /* 00000CF8    "A...._CI" */
-    0x44,0x0C,0x41,0xD0,0x03,0x0B,0x14,0x09,  /* 00000D00    "D.A....." */
-    0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F,  /* 00000D08    "_STA...." */
-    0x08,0x5F,0x43,0x52,0x53,0x11,0x18,0x0A,  /* 00000D10    "._CRS..." */
-    0x15,0x47,0x01,0x60,0x00,0x60,0x00,0x00,  /* 00000D18    ".G.`.`.." */
-    0x01,0x47,0x01,0x64,0x00,0x64,0x00,0x00,  /* 00000D20    ".G.d.d.." */
-    0x01,0x22,0x02,0x00,0x79,0x00,0x5B,0x82,  /* 00000D28    "."..y.[." */
-    0x3A,0x46,0x44,0x43,0x30,0x08,0x5F,0x48,  /* 00000D30    ":FDC0._H" */
-    0x49,0x44,0x0C,0x41,0xD0,0x07,0x00,0x14,  /* 00000D38    "ID.A...." */
-    0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,  /* 00000D40    "._STA..." */
-    0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x1B,  /* 00000D48    ".._CRS.." */
-    0x0A,0x18,0x47,0x01,0xF0,0x03,0xF0,0x03,  /* 00000D50    "..G....." */
-    0x01,0x06,0x47,0x01,0xF7,0x03,0xF7,0x03,  /* 00000D58    "..G....." */
-    0x01,0x01,0x22,0x40,0x00,0x2A,0x04,0x00,  /* 00000D60    ".."@.*.." */
-    0x79,0x00,0x5B,0x82,0x35,0x55,0x41,0x52,  /* 00000D68    "y.[.5UAR" */
-    0x31,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,  /* 00000D70    "1._HID.A" */
-    0xD0,0x05,0x01,0x08,0x5F,0x55,0x49,0x44,  /* 00000D78    "...._UID" */
-    0x01,0x14,0x09,0x5F,0x53,0x54,0x41,0x00,  /* 00000D80    "..._STA." */
-    0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53,  /* 00000D88    "...._CRS" */
-    0x11,0x10,0x0A,0x0D,0x47,0x01,0xF8,0x03,  /* 00000D90    "....G..." */
-    0xF8,0x03,0x01,0x08,0x22,0x10,0x00,0x79,  /* 00000D98    "...."..y" */
-    0x00,0x5B,0x82,0x36,0x4C,0x54,0x50,0x31,  /* 00000DA0    ".[.6LTP1" */
-    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 00000DA8    "._HID.A." */
-    0x04,0x00,0x08,0x5F,0x55,0x49,0x44,0x0A,  /* 00000DB0    "..._UID." */
-    0x02,0x14,0x09,0x5F,0x53,0x54,0x41,0x00,  /* 00000DB8    "..._STA." */
-    0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53,  /* 00000DC0    "...._CRS" */
-    0x11,0x10,0x0A,0x0D,0x47,0x01,0x78,0x03,  /* 00000DC8    "....G.x." */
-    0x78,0x03,0x08,0x08,0x22,0x80,0x00,0x79,  /* 00000DD0    "x..."..y" */
-    0x00,
+    0x00,0x08,0x5F,0x53,0x35,0x5F,0x12,0x08,  /* 00000058    ".._S5_.." */
+    0x04,0x0A,0x07,0x0A,0x07,0x00,0x00,0x08,  /* 00000060    "........" */
+    0x50,0x49,0x43,0x44,0x00,0x14,0x0C,0x5F,  /* 00000068    "PICD..._" */
+    0x50,0x49,0x43,0x01,0x70,0x68,0x50,0x49,  /* 00000070    "PIC.phPI" */
+    0x43,0x44,0x10,0x44,0xD2,0x5F,0x53,0x42,  /* 00000078    "CD.D._SB" */
+    0x5F,0x5B,0x82,0x49,0x04,0x4D,0x45,0x4D,  /* 00000080    "_[.I.MEM" */
+    0x30,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,  /* 00000088    "0._HID.A" */
+    0xD0,0x0C,0x02,0x08,0x5F,0x43,0x52,0x53,  /* 00000090    "...._CRS" */
+    0x11,0x33,0x0A,0x30,0x8A,0x2B,0x00,0x00,  /* 00000098    ".3.0.+.." */
+    0x0D,0x03,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000000A0    "........" */
+    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000000A8    "........" */
+    0x00,0x00,0xFF,0xFF,0x09,0x00,0x00,0x00,  /* 000000B0    "........" */
+    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000000B8    "........" */
+    0x00,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,  /* 000000C0    "........" */
+    0x00,0x00,0x79,0x00,0x5B,0x82,0x41,0xCD,  /* 000000C8    "..y.[.A." */
+    0x50,0x43,0x49,0x30,0x08,0x5F,0x48,0x49,  /* 000000D0    "PCI0._HI" */
+    0x44,0x0C,0x41,0xD0,0x0A,0x03,0x08,0x5F,  /* 000000D8    "D.A...._" */
+    0x55,0x49,0x44,0x00,0x08,0x5F,0x41,0x44,  /* 000000E0    "UID.._AD" */
+    0x52,0x00,0x08,0x5F,0x42,0x42,0x4E,0x00,  /* 000000E8    "R.._BBN." */
+    0x14,0x44,0x08,0x5F,0x43,0x52,0x53,0x00,  /* 000000F0    ".D._CRS." */
+    0x08,0x50,0x52,0x54,0x30,0x11,0x42,0x07,  /* 000000F8    ".PRT0.B." */
+    0x0A,0x6E,0x88,0x0D,0x00,0x02,0x0F,0x00,  /* 00000100    ".n......" */
+    0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,  /* 00000108    "........" */
+    0x00,0x01,0x47,0x01,0xF8,0x0C,0xF8,0x0C,  /* 00000110    "..G....." */
+    0x01,0x08,0x88,0x0D,0x00,0x01,0x0C,0x03,  /* 00000118    "........" */
+    0x00,0x00,0x00,0x00,0xF7,0x0C,0x00,0x00,  /* 00000120    "........" */
+    0xF8,0x0C,0x88,0x0D,0x00,0x01,0x0C,0x03,  /* 00000128    "........" */
+    0x00,0x00,0x00,0x0D,0xFF,0xFF,0x00,0x00,  /* 00000130    "........" */
+    0x00,0xF3,0x87,0x17,0x00,0x00,0x0C,0x03,  /* 00000138    "........" */
+    0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,  /* 00000140    "........" */
+    0xFF,0xFF,0x0B,0x00,0x00,0x00,0x00,0x00,  /* 00000148    "........" */
+    0x00,0x00,0x02,0x00,0x87,0x17,0x00,0x00,  /* 00000150    "........" */
+    0x0D,0x03,0x00,0x00,0x00,0x00,0x00,0x00,  /* 00000158    "........" */
+    0x00,0xF0,0xFF,0xFF,0xFF,0xF4,0x00,0x00,  /* 00000160    "........" */
+    0x00,0x00,0x00,0x00,0x00,0x05,0x79,0x00,  /* 00000168    "......y." */
+    0xA4,0x50,0x52,0x54,0x30,0x08,0x42,0x55,  /* 00000170    ".PRT0.BU" */
+    0x46,0x41,0x11,0x09,0x0A,0x06,0x23,0x60,  /* 00000178    "FA....#`" */
+    0x0C,0x18,0x79,0x00,0x08,0x42,0x55,0x46,  /* 00000180    "..y..BUF" */
+    0x42,0x11,0x09,0x0A,0x06,0x23,0x00,0x00,  /* 00000188    "B....#.." */
+    0x18,0x79,0x00,0x8B,0x42,0x55,0x46,0x42,  /* 00000190    ".y..BUFB" */
+    0x01,0x49,0x52,0x51,0x56,0x5B,0x82,0x48,  /* 00000198    ".IRQV[.H" */
+    0x08,0x4C,0x4E,0x4B,0x41,0x08,0x5F,0x48,  /* 000001A0    ".LNKA._H" */
+    0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08,  /* 000001A8    "ID.A...." */
+    0x5F,0x55,0x49,0x44,0x01,0x14,0x1C,0x5F,  /* 000001B0    "_UID..._" */
+    0x53,0x54,0x41,0x00,0x7B,0x50,0x49,0x52,  /* 000001B8    "STA.{PIR" */
+    0x41,0x0A,0x80,0x60,0xA0,0x08,0x93,0x60,  /* 000001C0    "A..`...`" */
+    0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04,0xA4,  /* 000001C8    "........" */
+    0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52,0x53,  /* 000001D0    "...._PRS" */
+    0x00,0xA4,0x42,0x55,0x46,0x41,0x14,0x11,  /* 000001D8    "..BUFA.." */
+    0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,0x49,  /* 000001E0    "_DIS.}PI" */
+    0x52,0x41,0x0A,0x80,0x50,0x49,0x52,0x41,  /* 000001E8    "RA..PIRA" */
+    0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,0x7B,  /* 000001F0    ".._CRS.{" */
+    0x50,0x49,0x52,0x41,0x0A,0x0F,0x60,0x79,  /* 000001F8    "PIRA..`y" */
+    0x01,0x60,0x49,0x52,0x51,0x56,0xA4,0x42,  /* 00000200    ".`IRQV.B" */
+    0x55,0x46,0x42,0x14,0x1B,0x5F,0x53,0x52,  /* 00000208    "UFB.._SR" */
+    0x53,0x01,0x8B,0x68,0x01,0x49,0x52,0x51,  /* 00000210    "S..h.IRQ" */
+    0x31,0x82,0x49,0x52,0x51,0x31,0x60,0x76,  /* 00000218    "1.IRQ1`v" */
+    0x60,0x70,0x60,0x50,0x49,0x52,0x41,0x5B,  /* 00000220    "`p`PIRA[" */
+    0x82,0x49,0x08,0x4C,0x4E,0x4B,0x42,0x08,  /* 00000228    ".I.LNKB." */
+    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,  /* 00000230    "_HID.A.." */
+    0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A,0x02,  /* 00000238    ".._UID.." */
+    0x14,0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B,  /* 00000240    ".._STA.{" */
+    0x50,0x49,0x52,0x42,0x0A,0x80,0x60,0xA0,  /* 00000248    "PIRB..`." */
+    0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09,  /* 00000250    "..`....." */
+    0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F,  /* 00000258    "......._" */
+    0x50,0x52,0x53,0x00,0xA4,0x42,0x55,0x46,  /* 00000260    "PRS..BUF" */
+    0x41,0x14,0x11,0x5F,0x44,0x49,0x53,0x00,  /* 00000268    "A.._DIS." */
+    0x7D,0x50,0x49,0x52,0x42,0x0A,0x80,0x50,  /* 00000270    "}PIRB..P" */
+    0x49,0x52,0x42,0x14,0x1A,0x5F,0x43,0x52,  /* 00000278    "IRB.._CR" */
+    0x53,0x00,0x7B,0x50,0x49,0x52,0x42,0x0A,  /* 00000280    "S.{PIRB." */
+    0x0F,0x60,0x79,0x01,0x60,0x49,0x52,0x51,  /* 00000288    ".`y.`IRQ" */
+    0x56,0xA4,0x42,0x55,0x46,0x42,0x14,0x1B,  /* 00000290    "V.BUFB.." */
+    0x5F,0x53,0x52,0x53,0x01,0x8B,0x68,0x01,  /* 00000298    "_SRS..h." */
+    0x49,0x52,0x51,0x31,0x82,0x49,0x52,0x51,  /* 000002A0    "IRQ1.IRQ" */
+    0x31,0x60,0x76,0x60,0x70,0x60,0x50,0x49,  /* 000002A8    "1`v`p`PI" */
+    0x52,0x42,0x5B,0x82,0x49,0x08,0x4C,0x4E,  /* 000002B0    "RB[.I.LN" */
+    0x4B,0x43,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 000002B8    "KC._HID." */
+    0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55,0x49,  /* 000002C0    "A...._UI" */
+    0x44,0x0A,0x03,0x14,0x1C,0x5F,0x53,0x54,  /* 000002C8    "D...._ST" */
+    0x41,0x00,0x7B,0x50,0x49,0x52,0x43,0x0A,  /* 000002D0    "A.{PIRC." */
+    0x80,0x60,0xA0,0x08,0x93,0x60,0x0A,0x80,  /* 000002D8    ".`...`.." */
+    0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A,0x0B,  /* 000002E0    "........" */
+    0x14,0x0B,0x5F,0x50,0x52,0x53,0x00,0xA4,  /* 000002E8    ".._PRS.." */
+    0x42,0x55,0x46,0x41,0x14,0x11,0x5F,0x44,  /* 000002F0    "BUFA.._D" */
+    0x49,0x53,0x00,0x7D,0x50,0x49,0x52,0x43,  /* 000002F8    "IS.}PIRC" */
+    0x0A,0x80,0x50,0x49,0x52,0x43,0x14,0x1A,  /* 00000300    "..PIRC.." */
+    0x5F,0x43,0x52,0x53,0x00,0x7B,0x50,0x49,  /* 00000308    "_CRS.{PI" */
+    0x52,0x43,0x0A,0x0F,0x60,0x79,0x01,0x60,  /* 00000310    "RC..`y.`" */
+    0x49,0x52,0x51,0x56,0xA4,0x42,0x55,0x46,  /* 00000318    "IRQV.BUF" */
+    0x42,0x14,0x1B,0x5F,0x53,0x52,0x53,0x01,  /* 00000320    "B.._SRS." */
+    0x8B,0x68,0x01,0x49,0x52,0x51,0x31,0x82,  /* 00000328    ".h.IRQ1." */
+    0x49,0x52,0x51,0x31,0x60,0x76,0x60,0x70,  /* 00000330    "IRQ1`v`p" */
+    0x60,0x50,0x49,0x52,0x43,0x5B,0x82,0x49,  /* 00000338    "`PIRC[.I" */
+    0x08,0x4C,0x4E,0x4B,0x44,0x08,0x5F,0x48,  /* 00000340    ".LNKD._H" */
+    0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08,  /* 00000348    "ID.A...." */
+    0x5F,0x55,0x49,0x44,0x0A,0x04,0x14,0x1C,  /* 00000350    "_UID...." */
+    0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,0x49,  /* 00000358    "_STA.{PI" */
+    0x52,0x44,0x0A,0x80,0x60,0xA0,0x08,0x93,  /* 00000360    "RD..`..." */
+    0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04,  /* 00000368    "`......." */
+    0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52,  /* 00000370    "....._PR" */
+    0x53,0x00,0xA4,0x42,0x55,0x46,0x41,0x14,  /* 00000378    "S..BUFA." */
+    0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,  /* 00000380    "._DIS.}P" */
+    0x49,0x52,0x44,0x0A,0x80,0x50,0x49,0x52,  /* 00000388    "IRD..PIR" */
+    0x44,0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,  /* 00000390    "D.._CRS." */
+    0x7B,0x50,0x49,0x52,0x44,0x0A,0x0F,0x60,  /* 00000398    "{PIRD..`" */
+    0x79,0x01,0x60,0x49,0x52,0x51,0x56,0xA4,  /* 000003A0    "y.`IRQV." */
+    0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,0x53,  /* 000003A8    "BUFB.._S" */
+    0x52,0x53,0x01,0x8B,0x68,0x01,0x49,0x52,  /* 000003B0    "RS..h.IR" */
+    0x51,0x31,0x82,0x49,0x52,0x51,0x31,0x60,  /* 000003B8    "Q1.IRQ1`" */
+    0x76,0x60,0x70,0x60,0x50,0x49,0x52,0x44,  /* 000003C0    "v`p`PIRD" */
+    0x5B,0x82,0x3A,0x48,0x50,0x45,0x54,0x08,  /* 000003C8    "[.:HPET." */
+    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x01,  /* 000003D0    "_HID.A.." */
+    0x03,0x08,0x5F,0x55,0x49,0x44,0x00,0x08,  /* 000003D8    ".._UID.." */
+    0x5F,0x43,0x52,0x53,0x11,0x1F,0x0A,0x1C,  /* 000003E0    "_CRS...." */
+    0x87,0x17,0x00,0x00,0x0D,0x01,0x00,0x00,  /* 000003E8    "........" */
+    0x00,0x00,0x00,0x00,0xD0,0xFE,0xFF,0x03,  /* 000003F0    "........" */
+    0xD0,0xFE,0x00,0x00,0x00,0x00,0x00,0x04,  /* 000003F8    "........" */
+    0x00,0x00,0x79,0x00,0x14,0x16,0x5F,0x50,  /* 00000400    "..y..._P" */
+    0x52,0x54,0x00,0xA0,0x0A,0x50,0x49,0x43,  /* 00000408    "RT...PIC" */
+    0x44,0xA4,0x50,0x52,0x54,0x41,0xA4,0x50,  /* 00000410    "D.PRTA.P" */
+    0x52,0x54,0x50,0x08,0x50,0x52,0x54,0x50,  /* 00000418    "RTP.PRTP" */
+    0x12,0x49,0x36,0x3C,0x12,0x0D,0x04,0x0C,  /* 00000420    ".I6<...." */
+    0xFF,0xFF,0x01,0x00,0x00,0x4C,0x4E,0x4B,  /* 00000428    ".....LNK" */
+    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000430    "B......." */
+    0x01,0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00,  /* 00000438    "...LNKC." */
+    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x01,0x00,  /* 00000440    "........" */
+    0x0A,0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12,  /* 00000448    "..LNKD.." */
+    0x0E,0x04,0x0C,0xFF,0xFF,0x01,0x00,0x0A,  /* 00000450    "........" */
+    0x03,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,  /* 00000458    ".LNKA..." */
+    0x04,0x0C,0xFF,0xFF,0x02,0x00,0x00,0x4C,  /* 00000460    ".......L" */
+    0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,  /* 00000468    "NKC....." */
+    0xFF,0xFF,0x02,0x00,0x01,0x4C,0x4E,0x4B,  /* 00000470    ".....LNK" */
+    0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 00000478    "D......." */
+    0x02,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41,  /* 00000480    "....LNKA" */
+    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x02,  /* 00000488    "........" */
+    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00,  /* 00000490    "...LNKB." */
+    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x03,0x00,  /* 00000498    "........" */
+    0x00,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,  /* 000004A0    ".LNKD..." */
+    0x04,0x0C,0xFF,0xFF,0x03,0x00,0x01,0x4C,  /* 000004A8    ".......L" */
+    0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,  /* 000004B0    "NKA....." */
+    0xFF,0xFF,0x03,0x00,0x0A,0x02,0x4C,0x4E,  /* 000004B8    "......LN" */
+    0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 000004C0    "KB......" */
+    0xFF,0x03,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 000004C8    ".....LNK" */
+    0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 000004D0    "C......." */
+    0x04,0x00,0x00,0x4C,0x4E,0x4B,0x41,0x00,  /* 000004D8    "...LNKA." */
+    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x04,0x00,  /* 000004E0    "........" */
+    0x01,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,  /* 000004E8    ".LNKB..." */
+    0x04,0x0C,0xFF,0xFF,0x04,0x00,0x0A,0x02,  /* 000004F0    "........" */
+    0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04,  /* 000004F8    "LNKC...." */
+    0x0C,0xFF,0xFF,0x04,0x00,0x0A,0x03,0x4C,  /* 00000500    ".......L" */
+    0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,  /* 00000508    "NKD....." */
+    0xFF,0xFF,0x05,0x00,0x00,0x4C,0x4E,0x4B,  /* 00000510    ".....LNK" */
+    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000518    "B......." */
+    0x05,0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00,  /* 00000520    "...LNKC." */
+    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x05,0x00,  /* 00000528    "........" */
+    0x0A,0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12,  /* 00000530    "..LNKD.." */
+    0x0E,0x04,0x0C,0xFF,0xFF,0x05,0x00,0x0A,  /* 00000538    "........" */
+    0x03,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,  /* 00000540    ".LNKA..." */
+    0x04,0x0C,0xFF,0xFF,0x06,0x00,0x00,0x4C,  /* 00000548    ".......L" */
+    0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,  /* 00000550    "NKC....." */
+    0xFF,0xFF,0x06,0x00,0x01,0x4C,0x4E,0x4B,  /* 00000558    ".....LNK" */
+    0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 00000560    "D......." */
+    0x06,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41,  /* 00000568    "....LNKA" */
+    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x06,  /* 00000570    "........" */
+    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00,  /* 00000578    "...LNKB." */
+    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x07,0x00,  /* 00000580    "........" */
+    0x00,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,  /* 00000588    ".LNKD..." */
+    0x04,0x0C,0xFF,0xFF,0x07,0x00,0x01,0x4C,  /* 00000590    ".......L" */
+    0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,  /* 00000598    "NKA....." */
+    0xFF,0xFF,0x07,0x00,0x0A,0x02,0x4C,0x4E,  /* 000005A0    "......LN" */
+    0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 000005A8    "KB......" */
+    0xFF,0x07,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 000005B0    ".....LNK" */
+    0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 000005B8    "C......." */
+    0x08,0x00,0x00,0x4C,0x4E,0x4B,0x41,0x00,  /* 000005C0    "...LNKA." */
+    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x08,0x00,  /* 000005C8    "........" */
+    0x01,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,  /* 000005D0    ".LNKB..." */
+    0x04,0x0C,0xFF,0xFF,0x08,0x00,0x0A,0x02,  /* 000005D8    "........" */
+    0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04,  /* 000005E0    "LNKC...." */
+    0x0C,0xFF,0xFF,0x08,0x00,0x0A,0x03,0x4C,  /* 000005E8    ".......L" */
+    0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,  /* 000005F0    "NKD....." */
+    0xFF,0xFF,0x09,0x00,0x00,0x4C,0x4E,0x4B,  /* 000005F8    ".....LNK" */
+    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000600    "B......." */
+    0x09,0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00,  /* 00000608    "...LNKC." */
+    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x09,0x00,  /* 00000610    "........" */
+    0x0A,0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12,  /* 00000618    "..LNKD.." */
+    0x0E,0x04,0x0C,0xFF,0xFF,0x09,0x00,0x0A,  /* 00000620    "........" */
+    0x03,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,  /* 00000628    ".LNKA..." */
+    0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x00,0x4C,  /* 00000630    ".......L" */
+    0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,  /* 00000638    "NKC....." */
+    0xFF,0xFF,0x0A,0x00,0x01,0x4C,0x4E,0x4B,  /* 00000640    ".....LNK" */
+    0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 00000648    "D......." */
+    0x0A,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41,  /* 00000650    "....LNKA" */
+    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0A,  /* 00000658    "........" */
+    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00,  /* 00000660    "...LNKB." */
+    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0B,0x00,  /* 00000668    "........" */
+    0x00,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,  /* 00000670    ".LNKD..." */
+    0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x01,0x4C,  /* 00000678    ".......L" */
+    0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,  /* 00000680    "NKA....." */
+    0xFF,0xFF,0x0B,0x00,0x0A,0x02,0x4C,0x4E,  /* 00000688    "......LN" */
+    0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 00000690    "KB......" */
+    0xFF,0x0B,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 00000698    ".....LNK" */
+    0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 000006A0    "C......." */
+    0x0C,0x00,0x00,0x4C,0x4E,0x4B,0x41,0x00,  /* 000006A8    "...LNKA." */
+    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0C,0x00,  /* 000006B0    "........" */
+    0x01,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,  /* 000006B8    ".LNKB..." */
+    0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x0A,0x02,  /* 000006C0    "........" */
+    0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04,  /* 000006C8    "LNKC...." */
+    0x0C,0xFF,0xFF,0x0C,0x00,0x0A,0x03,0x4C,  /* 000006D0    ".......L" */
+    0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,  /* 000006D8    "NKD....." */
+    0xFF,0xFF,0x0D,0x00,0x00,0x4C,0x4E,0x4B,  /* 000006E0    ".....LNK" */
+    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 000006E8    "B......." */
+    0x0D,0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00,  /* 000006F0    "...LNKC." */
+    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0D,0x00,  /* 000006F8    "........" */
+    0x0A,0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12,  /* 00000700    "..LNKD.." */
+    0x0E,0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x0A,  /* 00000708    "........" */
+    0x03,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,  /* 00000710    ".LNKA..." */
+    0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x00,0x4C,  /* 00000718    ".......L" */
+    0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,  /* 00000720    "NKC....." */
+    0xFF,0xFF,0x0E,0x00,0x01,0x4C,0x4E,0x4B,  /* 00000728    ".....LNK" */
+    0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 00000730    "D......." */
+    0x0E,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41,  /* 00000738    "....LNKA" */
+    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0E,  /* 00000740    "........" */
+    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00,  /* 00000748    "...LNKB." */
+    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0F,0x00,  /* 00000750    "........" */
+    0x00,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,  /* 00000758    ".LNKD..." */
+    0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x01,0x4C,  /* 00000760    ".......L" */
+    0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,  /* 00000768    "NKA....." */
+    0xFF,0xFF,0x0F,0x00,0x0A,0x02,0x4C,0x4E,  /* 00000770    "......LN" */
+    0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 00000778    "KB......" */
+    0xFF,0x0F,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 00000780    ".....LNK" */
+    0x43,0x00,0x08,0x50,0x52,0x54,0x41,0x12,  /* 00000788    "C..PRTA." */
+    0x41,0x2F,0x3C,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000790    "A/<....." */
+    0xFF,0x01,0x00,0x00,0x00,0x0A,0x14,0x12,  /* 00000798    "........" */
+    0x0B,0x04,0x0C,0xFF,0xFF,0x01,0x00,0x01,  /* 000007A0    "........" */
+    0x00,0x0A,0x15,0x12,0x0C,0x04,0x0C,0xFF,  /* 000007A8    "........" */
+    0xFF,0x01,0x00,0x0A,0x02,0x00,0x0A,0x16,  /* 000007B0    "........" */
+    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x01,0x00,  /* 000007B8    "........" */
+    0x0A,0x03,0x00,0x0A,0x17,0x12,0x0B,0x04,  /* 000007C0    "........" */
+    0x0C,0xFF,0xFF,0x02,0x00,0x00,0x00,0x0A,  /* 000007C8    "........" */
+    0x18,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x02,  /* 000007D0    "........" */
+    0x00,0x01,0x00,0x0A,0x19,0x12,0x0C,0x04,  /* 000007D8    "........" */
+    0x0C,0xFF,0xFF,0x02,0x00,0x0A,0x02,0x00,  /* 000007E0    "........" */
+    0x0A,0x1A,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 000007E8    "........" */
+    0x02,0x00,0x0A,0x03,0x00,0x0A,0x1B,0x12,  /* 000007F0    "........" */
+    0x0B,0x04,0x0C,0xFF,0xFF,0x03,0x00,0x00,  /* 000007F8    "........" */
+    0x00,0x0A,0x1C,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000800    "........" */
+    0xFF,0x03,0x00,0x01,0x00,0x0A,0x1D,0x12,  /* 00000808    "........" */
+    0x0C,0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A,  /* 00000810    "........" */
+    0x02,0x00,0x0A,0x1E,0x12,0x0C,0x04,0x0C,  /* 00000818    "........" */
+    0xFF,0xFF,0x03,0x00,0x0A,0x03,0x00,0x0A,  /* 00000820    "........" */
+    0x1F,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x04,  /* 00000828    "........" */
+    0x00,0x00,0x00,0x0A,0x20,0x12,0x0B,0x04,  /* 00000830    ".... ..." */
+    0x0C,0xFF,0xFF,0x04,0x00,0x01,0x00,0x0A,  /* 00000838    "........" */
+    0x21,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x04,  /* 00000840    "!......." */
+    0x00,0x0A,0x02,0x00,0x0A,0x22,0x12,0x0C,  /* 00000848    ".....".." */
+    0x04,0x0C,0xFF,0xFF,0x04,0x00,0x0A,0x03,  /* 00000850    "........" */
+    0x00,0x0A,0x23,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000858    "..#....." */
+    0xFF,0x05,0x00,0x00,0x00,0x0A,0x24,0x12,  /* 00000860    "......$." */
+    0x0B,0x04,0x0C,0xFF,0xFF,0x05,0x00,0x01,  /* 00000868    "........" */
+    0x00,0x0A,0x25,0x12,0x0C,0x04,0x0C,0xFF,  /* 00000870    "..%....." */
+    0xFF,0x05,0x00,0x0A,0x02,0x00,0x0A,0x26,  /* 00000878    ".......&" */
+    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x05,0x00,  /* 00000880    "........" */
+    0x0A,0x03,0x00,0x0A,0x27,0x12,0x0B,0x04,  /* 00000888    "....'..." */
+    0x0C,0xFF,0xFF,0x06,0x00,0x00,0x00,0x0A,  /* 00000890    "........" */
+    0x28,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x06,  /* 00000898    "(......." */
+    0x00,0x01,0x00,0x0A,0x29,0x12,0x0C,0x04,  /* 000008A0    "....)..." */
+    0x0C,0xFF,0xFF,0x06,0x00,0x0A,0x02,0x00,  /* 000008A8    "........" */
+    0x0A,0x2A,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 000008B0    ".*......" */
+    0x06,0x00,0x0A,0x03,0x00,0x0A,0x2B,0x12,  /* 000008B8    "......+." */
+    0x0B,0x04,0x0C,0xFF,0xFF,0x07,0x00,0x00,  /* 000008C0    "........" */
+    0x00,0x0A,0x2C,0x12,0x0B,0x04,0x0C,0xFF,  /* 000008C8    "..,....." */
+    0xFF,0x07,0x00,0x01,0x00,0x0A,0x2D,0x12,  /* 000008D0    "......-." */
+    0x0C,0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A,  /* 000008D8    "........" */
+    0x02,0x00,0x0A,0x2E,0x12,0x0C,0x04,0x0C,  /* 000008E0    "........" */
+    0xFF,0xFF,0x07,0x00,0x0A,0x03,0x00,0x0A,  /* 000008E8    "........" */
+    0x2F,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x08,  /* 000008F0    "/......." */
+    0x00,0x00,0x00,0x0A,0x11,0x12,0x0B,0x04,  /* 000008F8    "........" */
+    0x0C,0xFF,0xFF,0x08,0x00,0x01,0x00,0x0A,  /* 00000900    "........" */
+    0x12,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x08,  /* 00000908    "........" */
+    0x00,0x0A,0x02,0x00,0x0A,0x13,0x12,0x0C,  /* 00000910    "........" */
+    0x04,0x0C,0xFF,0xFF,0x08,0x00,0x0A,0x03,  /* 00000918    "........" */
+    0x00,0x0A,0x14,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000920    "........" */
+    0xFF,0x09,0x00,0x00,0x00,0x0A,0x15,0x12,  /* 00000928    "........" */
+    0x0B,0x04,0x0C,0xFF,0xFF,0x09,0x00,0x01,  /* 00000930    "........" */
+    0x00,0x0A,0x16,0x12,0x0C,0x04,0x0C,0xFF,  /* 00000938    "........" */
+    0xFF,0x09,0x00,0x0A,0x02,0x00,0x0A,0x17,  /* 00000940    "........" */
+    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x09,0x00,  /* 00000948    "........" */
+    0x0A,0x03,0x00,0x0A,0x18,0x12,0x0B,0x04,  /* 00000950    "........" */
+    0x0C,0xFF,0xFF,0x0A,0x00,0x00,0x00,0x0A,  /* 00000958    "........" */
+    0x19,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0A,  /* 00000960    "........" */
+    0x00,0x01,0x00,0x0A,0x1A,0x12,0x0C,0x04,  /* 00000968    "........" */
+    0x0C,0xFF,0xFF,0x0A,0x00,0x0A,0x02,0x00,  /* 00000970    "........" */
+    0x0A,0x1B,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000978    "........" */
+    0x0A,0x00,0x0A,0x03,0x00,0x0A,0x1C,0x12,  /* 00000980    "........" */
+    0x0B,0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x00,  /* 00000988    "........" */
+    0x00,0x0A,0x1D,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000990    "........" */
+    0xFF,0x0B,0x00,0x01,0x00,0x0A,0x1E,0x12,  /* 00000998    "........" */
+    0x0C,0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A,  /* 000009A0    "........" */
+    0x02,0x00,0x0A,0x1F,0x12,0x0C,0x04,0x0C,  /* 000009A8    "........" */
+    0xFF,0xFF,0x0B,0x00,0x0A,0x03,0x00,0x0A,  /* 000009B0    "........" */
+    0x20,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0C,  /* 000009B8    " ......." */
+    0x00,0x00,0x00,0x0A,0x21,0x12,0x0B,0x04,  /* 000009C0    "....!..." */
+    0x0C,0xFF,0xFF,0x0C,0x00,0x01,0x00,0x0A,  /* 000009C8    "........" */
+    0x22,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0C,  /* 000009D0    ""......." */
+    0x00,0x0A,0x02,0x00,0x0A,0x23,0x12,0x0C,  /* 000009D8    ".....#.." */
+    0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x0A,0x03,  /* 000009E0    "........" */
+    0x00,0x0A,0x24,0x12,0x0B,0x04,0x0C,0xFF,  /* 000009E8    "..$....." */
+    0xFF,0x0D,0x00,0x00,0x00,0x0A,0x25,0x12,  /* 000009F0    "......%." */
+    0x0B,0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x01,  /* 000009F8    "........" */
+    0x00,0x0A,0x26,0x12,0x0C,0x04,0x0C,0xFF,  /* 00000A00    "..&....." */
+    0xFF,0x0D,0x00,0x0A,0x02,0x00,0x0A,0x27,  /* 00000A08    ".......'" */
+    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0D,0x00,  /* 00000A10    "........" */
+    0x0A,0x03,0x00,0x0A,0x28,0x12,0x0B,0x04,  /* 00000A18    "....(..." */
+    0x0C,0xFF,0xFF,0x0E,0x00,0x00,0x00,0x0A,  /* 00000A20    "........" */
+    0x29,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0E,  /* 00000A28    ")......." */
+    0x00,0x01,0x00,0x0A,0x2A,0x12,0x0C,0x04,  /* 00000A30    "....*..." */
+    0x0C,0xFF,0xFF,0x0E,0x00,0x0A,0x02,0x00,  /* 00000A38    "........" */
+    0x0A,0x2B,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000A40    ".+......" */
+    0x0E,0x00,0x0A,0x03,0x00,0x0A,0x2C,0x12,  /* 00000A48    "......,." */
+    0x0B,0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x00,  /* 00000A50    "........" */
+    0x00,0x0A,0x2D,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000A58    "..-....." */
+    0xFF,0x0F,0x00,0x01,0x00,0x0A,0x2E,0x12,  /* 00000A60    "........" */
+    0x0C,0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A,  /* 00000A68    "........" */
+    0x02,0x00,0x0A,0x2F,0x12,0x0C,0x04,0x0C,  /* 00000A70    ".../...." */
+    0xFF,0xFF,0x0F,0x00,0x0A,0x03,0x00,0x0A,  /* 00000A78    "........" */
+    0x10,0x5B,0x82,0x4C,0x31,0x49,0x53,0x41,  /* 00000A80    ".[.L1ISA" */
+    0x5F,0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,  /* 00000A88    "_._ADR.." */
+    0x00,0x01,0x00,0x5B,0x80,0x50,0x49,0x52,  /* 00000A90    "...[.PIR" */
+    0x51,0x02,0x0A,0x60,0x0A,0x04,0x10,0x2E,  /* 00000A98    "Q..`...." */
+    0x5C,0x00,0x5B,0x81,0x29,0x5C,0x2F,0x04,  /* 00000AA0    "\.[.)\/." */
+    0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,0x30,  /* 00000AA8    "_SB_PCI0" */
+    0x49,0x53,0x41,0x5F,0x50,0x49,0x52,0x51,  /* 00000AB0    "ISA_PIRQ" */
+    0x01,0x50,0x49,0x52,0x41,0x08,0x50,0x49,  /* 00000AB8    ".PIRA.PI" */
+    0x52,0x42,0x08,0x50,0x49,0x52,0x43,0x08,  /* 00000AC0    "RB.PIRC." */
+    0x50,0x49,0x52,0x44,0x08,0x5B,0x82,0x46,  /* 00000AC8    "PIRD.[.F" */
+    0x0B,0x53,0x59,0x53,0x52,0x08,0x5F,0x48,  /* 00000AD0    ".SYSR._H" */
+    0x49,0x44,0x0C,0x41,0xD0,0x0C,0x02,0x08,  /* 00000AD8    "ID.A...." */
+    0x5F,0x55,0x49,0x44,0x01,0x08,0x43,0x52,  /* 00000AE0    "_UID..CR" */
+    0x53,0x5F,0x11,0x4E,0x08,0x0A,0x8A,0x47,  /* 00000AE8    "S_.N...G" */
+    0x01,0x10,0x00,0x10,0x00,0x00,0x10,0x47,  /* 00000AF0    ".......G" */
+    0x01,0x22,0x00,0x22,0x00,0x00,0x0C,0x47,  /* 00000AF8    "."."...G" */
+    0x01,0x30,0x00,0x30,0x00,0x00,0x10,0x47,  /* 00000B00    ".0.0...G" */
+    0x01,0x44,0x00,0x44,0x00,0x00,0x1C,0x47,  /* 00000B08    ".D.D...G" */
+    0x01,0x62,0x00,0x62,0x00,0x00,0x02,0x47,  /* 00000B10    ".b.b...G" */
+    0x01,0x65,0x00,0x65,0x00,0x00,0x0B,0x47,  /* 00000B18    ".e.e...G" */
+    0x01,0x72,0x00,0x72,0x00,0x00,0x0E,0x47,  /* 00000B20    ".r.r...G" */
+    0x01,0x80,0x00,0x80,0x00,0x00,0x01,0x47,  /* 00000B28    ".......G" */
+    0x01,0x84,0x00,0x84,0x00,0x00,0x03,0x47,  /* 00000B30    ".......G" */
+    0x01,0x88,0x00,0x88,0x00,0x00,0x01,0x47,  /* 00000B38    ".......G" */
+    0x01,0x8C,0x00,0x8C,0x00,0x00,0x03,0x47,  /* 00000B40    ".......G" */
+    0x01,0x90,0x00,0x90,0x00,0x00,0x10,0x47,  /* 00000B48    ".......G" */
+    0x01,0xA2,0x00,0xA2,0x00,0x00,0x1C,0x47,  /* 00000B50    ".......G" */
+    0x01,0xE0,0x00,0xE0,0x00,0x00,0x10,0x47,  /* 00000B58    ".......G" */
+    0x01,0xA0,0x08,0xA0,0x08,0x00,0x04,0x47,  /* 00000B60    ".......G" */
+    0x01,0xC0,0x0C,0xC0,0x0C,0x00,0x10,0x47,  /* 00000B68    ".......G" */
+    0x01,0xD0,0x04,0xD0,0x04,0x00,0x02,0x79,  /* 00000B70    ".......y" */
+    0x00,0x14,0x0B,0x5F,0x43,0x52,0x53,0x00,  /* 00000B78    "..._CRS." */
+    0xA4,0x43,0x52,0x53,0x5F,0x5B,0x82,0x2B,  /* 00000B80    ".CRS_[.+" */
+    0x50,0x49,0x43,0x5F,0x08,0x5F,0x48,0x49,  /* 00000B88    "PIC_._HI" */
+    0x44,0x0B,0x41,0xD0,0x08,0x5F,0x43,0x52,  /* 00000B90    "D.A.._CR" */
+    0x53,0x11,0x18,0x0A,0x15,0x47,0x01,0x20,  /* 00000B98    "S....G. " */
+    0x00,0x20,0x00,0x01,0x02,0x47,0x01,0xA0,  /* 00000BA0    ". ...G.." */
+    0x00,0xA0,0x00,0x01,0x02,0x22,0x04,0x00,  /* 00000BA8    ".....".." */
+    0x79,0x00,0x5B,0x82,0x47,0x05,0x44,0x4D,  /* 00000BB0    "y.[.G.DM" */
+    0x41,0x30,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 00000BB8    "A0._HID." */
+    0x41,0xD0,0x02,0x00,0x08,0x5F,0x43,0x52,  /* 00000BC0    "A...._CR" */
+    0x53,0x11,0x41,0x04,0x0A,0x3D,0x2A,0x10,  /* 00000BC8    "S.A..=*." */
+    0x04,0x47,0x01,0x00,0x00,0x00,0x00,0x00,  /* 00000BD0    ".G......" */
+    0x10,0x47,0x01,0x81,0x00,0x81,0x00,0x00,  /* 00000BD8    ".G......" */
+    0x03,0x47,0x01,0x87,0x00,0x87,0x00,0x00,  /* 00000BE0    ".G......" */
+    0x01,0x47,0x01,0x89,0x00,0x89,0x00,0x00,  /* 00000BE8    ".G......" */
+    0x03,0x47,0x01,0x8F,0x00,0x8F,0x00,0x00,  /* 00000BF0    ".G......" */
+    0x01,0x47,0x01,0xC0,0x00,0xC0,0x00,0x00,  /* 00000BF8    ".G......" */
+    0x20,0x47,0x01,0x80,0x04,0x80,0x04,0x00,  /* 00000C00    " G......" */
+    0x10,0x79,0x00,0x5B,0x82,0x25,0x54,0x4D,  /* 00000C08    ".y.[.%TM" */
+    0x52,0x5F,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 00000C10    "R_._HID." */
+    0x41,0xD0,0x01,0x00,0x08,0x5F,0x43,0x52,  /* 00000C18    "A...._CR" */
+    0x53,0x11,0x10,0x0A,0x0D,0x47,0x01,0x40,  /* 00000C20    "S....G.@" */
+    0x00,0x40,0x00,0x00,0x04,0x22,0x01,0x00,  /* 00000C28    ".@...".." */
+    0x79,0x00,0x5B,0x82,0x25,0x52,0x54,0x43,  /* 00000C30    "y.[.%RTC" */
+    0x5F,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,  /* 00000C38    "_._HID.A" */
+    0xD0,0x0B,0x00,0x08,0x5F,0x43,0x52,0x53,  /* 00000C40    "...._CRS" */
+    0x11,0x10,0x0A,0x0D,0x47,0x01,0x70,0x00,  /* 00000C48    "....G.p." */
+    0x70,0x00,0x00,0x02,0x22,0x00,0x01,0x79,  /* 00000C50    "p..."..y" */
+    0x00,0x5B,0x82,0x22,0x53,0x50,0x4B,0x52,  /* 00000C58    ".[."SPKR" */
+    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 00000C60    "._HID.A." */
+    0x08,0x00,0x08,0x5F,0x43,0x52,0x53,0x11,  /* 00000C68    "..._CRS." */
+    0x0D,0x0A,0x0A,0x47,0x01,0x61,0x00,0x61,  /* 00000C70    "...G.a.a" */
+    0x00,0x00,0x01,0x79,0x00,0x5B,0x82,0x31,  /* 00000C78    "...y.[.1" */
+    0x50,0x53,0x32,0x4D,0x08,0x5F,0x48,0x49,  /* 00000C80    "PS2M._HI" */
+    0x44,0x0C,0x41,0xD0,0x0F,0x13,0x08,0x5F,  /* 00000C88    "D.A...._" */
+    0x43,0x49,0x44,0x0C,0x41,0xD0,0x0F,0x13,  /* 00000C90    "CID.A..." */
+    0x14,0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,  /* 00000C98    ".._STA.." */
+    0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,  /* 00000CA0    "..._CRS." */
+    0x08,0x0A,0x05,0x22,0x00,0x10,0x79,0x00,  /* 00000CA8    "..."..y." */
+    0x5B,0x82,0x42,0x04,0x50,0x53,0x32,0x4B,  /* 00000CB0    "[.B.PS2K" */
+    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 00000CB8    "._HID.A." */
+    0x03,0x03,0x08,0x5F,0x43,0x49,0x44,0x0C,  /* 00000CC0    "..._CID." */
+    0x41,0xD0,0x03,0x0B,0x14,0x09,0x5F,0x53,  /* 00000CC8    "A....._S" */
+    0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F,  /* 00000CD0    "TA....._" */
+    0x43,0x52,0x53,0x11,0x18,0x0A,0x15,0x47,  /* 00000CD8    "CRS....G" */
+    0x01,0x60,0x00,0x60,0x00,0x00,0x01,0x47,  /* 00000CE0    ".`.`...G" */
+    0x01,0x64,0x00,0x64,0x00,0x00,0x01,0x22,  /* 00000CE8    ".d.d..."" */
+    0x02,0x00,0x79,0x00,0x5B,0x82,0x3A,0x46,  /* 00000CF0    "..y.[.:F" */
+    0x44,0x43,0x30,0x08,0x5F,0x48,0x49,0x44,  /* 00000CF8    "DC0._HID" */
+    0x0C,0x41,0xD0,0x07,0x00,0x14,0x09,0x5F,  /* 00000D00    ".A....._" */
+    0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08,  /* 00000D08    "STA....." */
+    0x5F,0x43,0x52,0x53,0x11,0x1B,0x0A,0x18,  /* 00000D10    "_CRS...." */
+    0x47,0x01,0xF0,0x03,0xF0,0x03,0x01,0x06,  /* 00000D18    "G......." */
+    0x47,0x01,0xF7,0x03,0xF7,0x03,0x01,0x01,  /* 00000D20    "G......." */
+    0x22,0x40,0x00,0x2A,0x04,0x00,0x79,0x00,  /* 00000D28    ""@.*..y." */
+    0x5B,0x82,0x35,0x55,0x41,0x52,0x31,0x08,  /* 00000D30    "[.5UAR1." */
+    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x05,  /* 00000D38    "_HID.A.." */
+    0x01,0x08,0x5F,0x55,0x49,0x44,0x01,0x14,  /* 00000D40    ".._UID.." */
+    0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,  /* 00000D48    "._STA..." */
+    0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x10,  /* 00000D50    ".._CRS.." */
+    0x0A,0x0D,0x47,0x01,0xF8,0x03,0xF8,0x03,  /* 00000D58    "..G....." */
+    0x01,0x08,0x22,0x10,0x00,0x79,0x00,0x5B,  /* 00000D60    ".."..y.[" */
+    0x82,0x36,0x4C,0x54,0x50,0x31,0x08,0x5F,  /* 00000D68    ".6LTP1._" */
+    0x48,0x49,0x44,0x0C,0x41,0xD0,0x04,0x00,  /* 00000D70    "HID.A..." */
+    0x08,0x5F,0x55,0x49,0x44,0x0A,0x02,0x14,  /* 00000D78    "._UID..." */
+    0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,  /* 00000D80    "._STA..." */
+    0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x10,  /* 00000D88    ".._CRS.." */
+    0x0A,0x0D,0x47,0x01,0x78,0x03,0x78,0x03,  /* 00000D90    "..G.x.x." */
+    0x08,0x08,0x22,0x80,0x00,0x79,0x00,
 };
 int DsdtLen=sizeof(AmlCode);
diff -r 04c23c1ef888 -r d907467f08cd tools/firmware/rombios/32bit/Makefile
--- a/tools/firmware/rombios/32bit/Makefile     Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/firmware/rombios/32bit/Makefile     Tue Feb 20 12:58:22 2007 -0700
@@ -9,6 +9,8 @@ TARGET = 32bitbios_flat.h
 
 CFLAGS += -fno-builtin -O2 -msoft-float -nostdlib
 CFLAGS += -I../ -DGCC_PROTOS
+CFLAGS += $(call cc-option,$(CC),-fno-stack-protector,)
+CFLAGS += $(call cc-option,$(CC),-fno-stack-protector-all,)
 
 SUBDIRS = tcgbios
 
diff -r 04c23c1ef888 -r d907467f08cd 
tools/firmware/rombios/32bit/tcgbios/Makefile
--- a/tools/firmware/rombios/32bit/tcgbios/Makefile     Sun Feb 18 16:13:13 
2007 -0700
+++ b/tools/firmware/rombios/32bit/tcgbios/Makefile     Tue Feb 20 12:58:22 
2007 -0700
@@ -9,6 +9,8 @@ OBJECTS = $(foreach f,$(FILES),$(f).o)
 OBJECTS = $(foreach f,$(FILES),$(f).o)
 
 CFLAGS += -fno-builtin -O2 -msoft-float -nostdlib
+CFLAGS += $(call cc-option,$(CC),-fno-stack-protector,)
+CFLAGS += $(call cc-option,$(CC),-fno-stack-protector-all,)
 CFLAGS += -I../ -I../../ -DGCC_PROTOS
 
 .PHONY: all clean
diff -r 04c23c1ef888 -r d907467f08cd tools/ioemu/hw/tpm_tis.c
--- a/tools/ioemu/hw/tpm_tis.c  Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/ioemu/hw/tpm_tis.c  Tue Feb 20 12:58:22 2007 -0700
@@ -769,6 +769,8 @@ static void tpm_save(QEMUFile* f,void* o
             if (n > 0) {
                 if (IS_VALID_LOC(s->active_loc)) {
                     s->loc[s->active_loc].sts = STS_VALID | STS_DATA_AVAILABLE;
+                    s->loc[s->active_loc].state = STATE_COMPLETION;
+                    tis_raise_irq(s, s->active_loc, INT_DATA_AVAILABLE);
                 }
                 /* close the connection with the vTPM for good */
                 close_vtpm_channel(s, 1);
@@ -881,6 +883,7 @@ void tpm_tis_init(SetIRQFunc *set_irq, v
     s->Transmitlayer = -1;
     s->tpmTx.fd[0] = -1;
     s->tpmTx.fd[1] = -1;
+    s->aborting_locty = NO_LOCALITY;
 
     tpm_initialize_instance(s, s->vtpm_instance);
     memset(s->buffer.buf,0,sizeof(s->buffer.buf));
diff -r 04c23c1ef888 -r d907467f08cd tools/libfsimage/common/fsimage.c
--- a/tools/libfsimage/common/fsimage.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libfsimage/common/fsimage.c Tue Feb 20 12:58:22 2007 -0700
@@ -36,7 +36,7 @@
 
 static pthread_mutex_t fsi_lock = PTHREAD_MUTEX_INITIALIZER;
 
-fsi_t *fsi_open_fsimage(const char *path, uint64_t off)
+fsi_t *fsi_open_fsimage(const char *path, uint64_t off, const char *options)
 {
        fsi_t *fsi = NULL;
        int fd;
@@ -53,7 +53,7 @@ fsi_t *fsi_open_fsimage(const char *path
        fsi->f_data = NULL;
 
        pthread_mutex_lock(&fsi_lock);
-       err = find_plugin(fsi, path);
+       err = find_plugin(fsi, path, options);
        pthread_mutex_unlock(&fsi_lock);
        if (err != 0)
                goto fail;
diff -r 04c23c1ef888 -r d907467f08cd tools/libfsimage/common/fsimage.h
--- a/tools/libfsimage/common/fsimage.h Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libfsimage/common/fsimage.h Tue Feb 20 12:58:22 2007 -0700
@@ -35,7 +35,7 @@ typedef struct fsi fsi_t;
 typedef struct fsi fsi_t;
 typedef struct fsi_file fsi_file_t;
 
-fsi_t *fsi_open_fsimage(const char *, uint64_t);
+fsi_t *fsi_open_fsimage(const char *, uint64_t, const char *);
 void fsi_close_fsimage(fsi_t *);
 
 int fsi_file_exists(fsi_t *, const char *);
diff -r 04c23c1ef888 -r d907467f08cd tools/libfsimage/common/fsimage_grub.c
--- a/tools/libfsimage/common/fsimage_grub.c    Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libfsimage/common/fsimage_grub.c    Tue Feb 20 12:58:22 2007 -0700
@@ -161,7 +161,7 @@ fsig_substring(const char *s1, const cha
 }
 
 static int
-fsig_mount(fsi_t *fsi, const char *path)
+fsig_mount(fsi_t *fsi, const char *path, const char *options)
 {
        fsig_plugin_ops_t *ops = fsi->f_plugin->fp_data;
        fsi_file_t *ffi;
@@ -178,7 +178,7 @@ fsig_mount(fsi_t *fsi, const char *path)
 
        bzero(fsi->f_data, sizeof (fsig_data_t));
 
-       if (!ops->fpo_mount(ffi)) {
+       if (!ops->fpo_mount(ffi, options)) {
                fsip_file_free(ffi);
                free(fsi->f_data);
                fsi->f_data = NULL;
diff -r 04c23c1ef888 -r d907467f08cd tools/libfsimage/common/fsimage_grub.h
--- a/tools/libfsimage/common/fsimage_grub.h    Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libfsimage/common/fsimage_grub.h    Tue Feb 20 12:58:22 2007 -0700
@@ -38,7 +38,7 @@ extern C {
 
 typedef struct fsig_plugin_ops {
        int fpo_version;
-       int (*fpo_mount)(fsi_file_t *);
+       int (*fpo_mount)(fsi_file_t *, const char *);
        int (*fpo_dir)(fsi_file_t *, char *);
        int (*fpo_read)(fsi_file_t *, char *, int);
 } fsig_plugin_ops_t;
diff -r 04c23c1ef888 -r d907467f08cd tools/libfsimage/common/fsimage_plugin.c
--- a/tools/libfsimage/common/fsimage_plugin.c  Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libfsimage/common/fsimage_plugin.c  Tue Feb 20 12:58:22 2007 -0700
@@ -185,7 +185,7 @@ fail:
        return (ret);
 }
 
-int find_plugin(fsi_t *fsi, const char *path)
+int find_plugin(fsi_t *fsi, const char *path, const char *options)
 {
        fsi_plugin_t *fp;
        int ret = 0;
@@ -195,7 +195,7 @@ int find_plugin(fsi_t *fsi, const char *
 
        for (fp = plugins; fp != NULL; fp = fp->fp_next) {
                fsi->f_plugin = fp;
-               if (fp->fp_ops->fpo_mount(fsi, path) == 0)
+               if (fp->fp_ops->fpo_mount(fsi, path, options) == 0)
                        goto out;
        }
 
diff -r 04c23c1ef888 -r d907467f08cd tools/libfsimage/common/fsimage_plugin.h
--- a/tools/libfsimage/common/fsimage_plugin.h  Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libfsimage/common/fsimage_plugin.h  Tue Feb 20 12:58:22 2007 -0700
@@ -38,7 +38,7 @@ typedef struct fsi_plugin fsi_plugin_t;
 
 typedef struct fsi_plugin_ops {
        int fpo_version;
-       int (*fpo_mount)(fsi_t *, const char *);
+       int (*fpo_mount)(fsi_t *, const char *, const char *);
        int (*fpo_umount)(fsi_t *);
        fsi_file_t *(*fpo_open)(fsi_t *, const char *);
        ssize_t (*fpo_read)(fsi_file_t *, void *, size_t);
diff -r 04c23c1ef888 -r d907467f08cd tools/libfsimage/common/fsimage_priv.h
--- a/tools/libfsimage/common/fsimage_priv.h    Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libfsimage/common/fsimage_priv.h    Tue Feb 20 12:58:22 2007 -0700
@@ -53,7 +53,7 @@ struct fsi_file {
        void *ff_data;
 };
 
-int find_plugin(fsi_t *, const char *);
+int find_plugin(fsi_t *, const char *, const char *);
 
 #ifdef __cplusplus
 };
diff -r 04c23c1ef888 -r d907467f08cd tools/libfsimage/ext2fs-lib/ext2fs-lib.c
--- a/tools/libfsimage/ext2fs-lib/ext2fs-lib.c  Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libfsimage/ext2fs-lib/ext2fs-lib.c  Tue Feb 20 12:58:22 2007 -0700
@@ -27,7 +27,7 @@
 #include <inttypes.h>
 
 static int
-ext2lib_mount(fsi_t *fsi, const char *name)
+ext2lib_mount(fsi_t *fsi, const char *name, const char *options)
 {
        int err;
        char opts[30] = "";
diff -r 04c23c1ef888 -r d907467f08cd tools/libfsimage/ext2fs/fsys_ext2fs.c
--- a/tools/libfsimage/ext2fs/fsys_ext2fs.c     Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libfsimage/ext2fs/fsys_ext2fs.c     Tue Feb 20 12:58:22 2007 -0700
@@ -321,7 +321,7 @@ ffz (unsigned long word)
 
 /* check filesystem types and read superblock into memory buffer */
 int
-ext2fs_mount (fsi_file_t *ffi)
+ext2fs_mount (fsi_file_t *ffi, const char *options)
 {
   int retval = 1;
 
diff -r 04c23c1ef888 -r d907467f08cd tools/libfsimage/reiserfs/fsys_reiserfs.c
--- a/tools/libfsimage/reiserfs/fsys_reiserfs.c Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libfsimage/reiserfs/fsys_reiserfs.c Tue Feb 20 12:58:22 2007 -0700
@@ -633,7 +633,7 @@ journal_init (fsi_file_t *ffi)
 
 /* check filesystem types and read superblock into memory buffer */
 int
-reiserfs_mount (fsi_file_t *ffi)
+reiserfs_mount (fsi_file_t *ffi, const char *options)
 {
   struct reiserfs_super_block super;
   int superblock = REISERFS_DISK_OFFSET_IN_BYTES >> SECTOR_BITS;
diff -r 04c23c1ef888 -r d907467f08cd tools/libfsimage/ufs/fsys_ufs.c
--- a/tools/libfsimage/ufs/fsys_ufs.c   Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libfsimage/ufs/fsys_ufs.c   Tue Feb 20 12:58:22 2007 -0700
@@ -44,7 +44,7 @@ static grub_daddr32_t sbmap(fsi_file_t *
 
 /* read superblock and check fs magic */
 int
-ufs_mount(fsi_file_t *ffi)
+ufs_mount(fsi_file_t *ffi, const char *options)
 {
        if (/*! IS_PC_SLICE_TYPE_SOLARIS(current_slice) || */
            !devread(ffi, UFS_SBLOCK, 0, UFS_SBSIZE, (char *)SUPERBLOCK) ||
diff -r 04c23c1ef888 -r d907467f08cd tools/libxc/Makefile
--- a/tools/libxc/Makefile      Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libxc/Makefile      Tue Feb 20 12:58:22 2007 -0700
@@ -22,11 +22,7 @@ CTRL_SRCS-$(CONFIG_X86_Linux) += xc_ptra
 CTRL_SRCS-$(CONFIG_X86_Linux) += xc_ptrace.c xc_ptrace_core.c
 
 GUEST_SRCS-y :=
-GUEST_SRCS-y += xc_load_bin.c
-GUEST_SRCS-y += xc_load_elf.c
 GUEST_SRCS-y += xg_private.c
-#GUEST_SRCS-$(CONFIG_X86) += xc_linux_build.c
-#GUEST_SRCS-$(CONFIG_IA64) += xc_linux_build.c
 GUEST_SRCS-$(CONFIG_MIGRATE) += xc_linux_restore.c xc_linux_save.c
 GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c xc_hvm_restore.c xc_hvm_save.c
 
diff -r 04c23c1ef888 -r d907467f08cd tools/libxc/xc_dom.h
--- a/tools/libxc/xc_dom.h      Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libxc/xc_dom.h      Tue Feb 20 12:58:22 2007 -0700
@@ -6,6 +6,8 @@
 
 typedef uint64_t xen_vaddr_t;
 typedef uint64_t xen_paddr_t;
+
+#define PRIpfn PRI_xen_pfn
 
 struct xc_dom_seg {
     xen_vaddr_t vstart;
diff -r 04c23c1ef888 -r d907467f08cd tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c   Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libxc/xc_domain.c   Tue Feb 20 12:58:22 2007 -0700
@@ -102,7 +102,7 @@ int xc_vcpu_setaffinity(int xc_handle,
     domctl.domain = (domid_t)domid;
     domctl.u.vcpuaffinity.vcpu    = vcpu;
 
-    bitmap_64_to_byte(local, &cpumap, sizeof (cpumap));
+    bitmap_64_to_byte(local, &cpumap, sizeof(cpumap) * 8);
 
     set_xen_guest_handle(domctl.u.vcpuaffinity.cpumap.bitmap, local);
 
@@ -148,7 +148,7 @@ int xc_vcpu_getaffinity(int xc_handle,
     ret = do_domctl(xc_handle, &domctl);
 
     unlock_pages(local, sizeof (local));
-    bitmap_byte_to_64(cpumap, local, sizeof (local));
+    bitmap_byte_to_64(cpumap, local, sizeof(local) * 8);
  out:
     return ret;
 }
diff -r 04c23c1ef888 -r d907467f08cd tools/libxc/xc_hvm_build.c
--- a/tools/libxc/xc_hvm_build.c        Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libxc/xc_hvm_build.c        Tue Feb 20 12:58:22 2007 -0700
@@ -214,15 +214,6 @@ static int setup_guest(int xc_handle,
             v_start, v_end,
             elf_uval(&elf, elf.ehdr, e_entry));
 
-    if ( (v_end - v_start) > ((unsigned long long)nr_pages << PAGE_SHIFT) )
-    {
-        PERROR("Initial guest OS requires too much space: "
-               "(%lluMB is greater than %lluMB limit)\n",
-               (unsigned long long)(v_end - v_start) >> 20,
-               ((unsigned long long)nr_pages << PAGE_SHIFT) >> 20);
-        goto error_out;
-    }
-
     if ( (page_array = malloc(nr_pages * sizeof(xen_pfn_t))) == NULL )
     {
         PERROR("Could not allocate memory.\n");
diff -r 04c23c1ef888 -r d907467f08cd tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c      Sun Feb 18 16:13:13 2007 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,1319 +0,0 @@
-/******************************************************************************
- * xc_linux_build.c
- */
-
-#include <stddef.h>
-#include "xg_private.h"
-#include "xc_private.h"
-#include <xenctrl.h>
-
-#include "xc_elf.h"
-#include <stdlib.h>
-#include <unistd.h>
-#include <inttypes.h>
-#include <zlib.h>
-
-/* Handy for printing out '0' prepended values at native pointer size */
-#define _p(a) ((void *) ((ulong)a))
-
-#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
-#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
-#if defined(__i386__)
-#define L3_PROT (_PAGE_PRESENT)
-#elif defined(__x86_64__)
-#define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
-#define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
-#endif
-
-#define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
-#define round_pgdown(_p)  ((_p)&PAGE_MASK)
-
-struct initrd_info {
-    enum { INITRD_none, INITRD_file, INITRD_mem } type;
-    /*
-     * .len must be filled in by the user for type==INITRD_mem. It is
-     * filled in by load_initrd() for INITRD_file and unused for
-     * INITRD_none.
-     */
-    unsigned long len;
-    union {
-        gzFile file_handle;
-        char *mem_addr;
-    } u;
-};
-
-static const char *feature_names[XENFEAT_NR_SUBMAPS*32] = {
-    [XENFEAT_writable_page_tables]       = "writable_page_tables",
-    [XENFEAT_writable_descriptor_tables] = "writable_descriptor_tables",
-    [XENFEAT_auto_translated_physmap]    = "auto_translated_physmap",
-    [XENFEAT_supervisor_mode_kernel]     = "supervisor_mode_kernel",
-    [XENFEAT_pae_pgdir_above_4gb]        = "pae_pgdir_above_4gb"
-};
-
-static inline void set_feature_bit (int nr, uint32_t *addr)
-{
-    addr[nr>>5] |= (1<<(nr&31));
-}
-
-static inline int test_feature_bit(int nr, uint32_t *addr)
-{
-    return !!(addr[nr>>5] & (1<<(nr&31)));
-}
-
-static int parse_features(
-    const char *feats,
-    uint32_t supported[XENFEAT_NR_SUBMAPS],
-    uint32_t required[XENFEAT_NR_SUBMAPS])
-{
-    const char *end, *p;
-    int i, req;
-
-    if ( (end = strchr(feats, ',')) == NULL )
-        end = feats + strlen(feats);
-
-    while ( feats < end )
-    {
-        p = strchr(feats, '|');
-        if ( (p == NULL) || (p > end) )
-            p = end;
-
-        req = (*feats == '!');
-        if ( req )
-            feats++;
-
-        for ( i = 0; i < XENFEAT_NR_SUBMAPS*32; i++ )
-        {
-            if ( feature_names[i] == NULL )
-                continue;
-
-            if ( strncmp(feature_names[i], feats, p-feats) == 0 )
-            {
-                set_feature_bit(i, supported);
-                if ( required && req )
-                    set_feature_bit(i, required);
-                break;
-            }
-        }
-
-        if ( i == XENFEAT_NR_SUBMAPS*32 )
-        {
-            ERROR("Unknown feature \"%.*s\".", (int)(p-feats), feats);
-            if ( req )
-            {
-                ERROR("Kernel requires an unknown hypervisor feature.");
-                return -EINVAL;
-            }
-        }
-
-        feats = p;
-        if ( *feats == '|' )
-            feats++;
-    }
-
-    return -EINVAL;
-}
-
-static int probeimageformat(const char *image,
-                            unsigned long image_size,
-                            struct load_funcs *load_funcs)
-{
-    if ( probe_elf(image, image_size, load_funcs) &&
-         probe_bin(image, image_size, load_funcs) )
-    {
-        xc_set_error(XC_INVALID_KERNEL, "Not a valid ELF or raw kernel image");
-        return -EINVAL;
-    }
-
-    return 0;
-}
-
-static int load_initrd(int xc_handle, domid_t dom,
-                struct initrd_info *initrd,
-                unsigned long physbase,
-                xen_pfn_t *phys_to_mach)
-{
-    char page[PAGE_SIZE];
-    unsigned long pfn_start, pfn;
-
-    if ( initrd->type == INITRD_none )
-        return 0;
-
-    pfn_start = physbase >> PAGE_SHIFT;
-
-    if ( initrd->type == INITRD_mem )
-    {
-        unsigned long nr_pages  = (initrd->len + PAGE_SIZE - 1) >> PAGE_SHIFT;
-
-        for ( pfn = pfn_start; pfn < (pfn_start + nr_pages); pfn++ )
-        {
-            xc_copy_to_domain_page(
-                xc_handle, dom, phys_to_mach[pfn],
-                &initrd->u.mem_addr[(pfn - pfn_start) << PAGE_SHIFT]);
-        }
-    }
-    else
-    {
-        int readlen;
-
-        pfn = pfn_start;
-        initrd->len = 0;
-
-        /* gzread returns 0 on EOF */
-        while ( (readlen = gzread(initrd->u.file_handle, page, PAGE_SIZE)) )
-        {
-            if ( readlen < 0 )
-            {
-                PERROR("Error reading initrd image, could not");
-                return -EINVAL;
-            }
-
-            initrd->len += readlen;
-            xc_copy_to_domain_page(xc_handle, dom, phys_to_mach[pfn++], page);
-        }
-    }
-
-    return 0;
-}
-
-#define alloc_pt(ltab, vltab)                                           \
-do {                                                                    \
-    ltab = ppt_alloc++;                                                 \
-    ltab = (uint64_t)page_array[ltab] << PAGE_SHIFT;                    \
-    if ( vltab != NULL )                                                \
-        munmap(vltab, PAGE_SIZE);                                       \
-    if ( (vltab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,       \
-                                       PROT_READ|PROT_WRITE,            \
-                                       ltab >> PAGE_SHIFT)) == NULL )   \
-        goto error_out;                                                 \
-    memset(vltab, 0x0, PAGE_SIZE);                                      \
-} while ( 0 )
-
-#if defined(__i386__)
-
-static int setup_pg_tables(int xc_handle, uint32_t dom,
-                           vcpu_guest_context_t *ctxt,
-                           unsigned long dsi_v_start,
-                           unsigned long v_end,
-                           xen_pfn_t *page_array,
-                           unsigned long vpt_start,
-                           unsigned long vpt_end,
-                           unsigned shadow_mode_enabled)
-{
-    l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
-    l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
-    unsigned long l1tab = 0;
-    unsigned long l2tab = 0;
-    unsigned long ppt_alloc;
-    unsigned long count;
-
-    ppt_alloc = (vpt_start - dsi_v_start) >> PAGE_SHIFT;
-    alloc_pt(l2tab, vl2tab);
-    vl2e = &vl2tab[l2_table_offset(dsi_v_start)];
-    ctxt->ctrlreg[3] = xen_pfn_to_cr3(l2tab >> PAGE_SHIFT);
-
-    for ( count = 0; count < ((v_end - dsi_v_start) >> PAGE_SHIFT); count++ )
-    {
-        if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
-        {
-            alloc_pt(l1tab, vl1tab);
-            vl1e = &vl1tab[l1_table_offset(dsi_v_start + (count<<PAGE_SHIFT))];
-            *vl2e++ = l1tab | L2_PROT;
-        }
-
-        *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
-
-        if ( !shadow_mode_enabled )
-            if ( (count >= ((vpt_start-dsi_v_start)>>PAGE_SHIFT)) &&
-                 (count <  ((vpt_end  -dsi_v_start)>>PAGE_SHIFT)) )
-                *vl1e &= ~_PAGE_RW;
-
-        vl1e++;
-    }
-    munmap(vl1tab, PAGE_SIZE);
-    munmap(vl2tab, PAGE_SIZE);
-    return 0;
-
- error_out:
-    if (vl1tab)
-        munmap(vl1tab, PAGE_SIZE);
-    if (vl2tab)
-        munmap(vl2tab, PAGE_SIZE);
-    return -1;
-}
-
-static int setup_pg_tables_pae(int xc_handle, uint32_t dom,
-                               vcpu_guest_context_t *ctxt,
-                               unsigned long dsi_v_start,
-                               unsigned long v_end,
-                               xen_pfn_t *page_array,
-                               unsigned long vpt_start,
-                               unsigned long vpt_end,
-                               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;
-    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);
-    vl3e = &vl3tab[l3_table_offset_pae(dsi_v_start)];
-    ctxt->ctrlreg[3] = xen_pfn_to_cr3(l3tab >> PAGE_SHIFT);
-
-    for ( count = 0; count < ((v_end - dsi_v_start) >> PAGE_SHIFT); count++)
-    {
-        if ( !((unsigned long)vl1e & (PAGE_SIZE-1)) )
-        {
-            if ( !((unsigned long)vl2e & (PAGE_SIZE-1)) )
-            {
-                alloc_pt(l2tab, vl2tab);
-                vl2e = &vl2tab[l2_table_offset_pae(
-                    dsi_v_start + (count << PAGE_SHIFT))];
-                *vl3e++ = l2tab | L3_PROT;
-            }
-
-            alloc_pt(l1tab, vl1tab);
-            vl1e = &vl1tab[l1_table_offset_pae(
-                dsi_v_start + (count << PAGE_SHIFT))];
-            *vl2e++ = l1tab | L2_PROT;
-
-        }
-
-        *vl1e = ((uint64_t)page_array[count] << PAGE_SHIFT) | L1_PROT;
-
-        if ( !shadow_mode_enabled )
-            if ( (count >= ((vpt_start-dsi_v_start)>>PAGE_SHIFT)) &&
-                 (count <  ((vpt_end  -dsi_v_start)>>PAGE_SHIFT)) )
-                *vl1e &= ~_PAGE_RW;
-
-        vl1e++;
-    }
-
-    /* Xen requires a mid-level pgdir mapping 0xC0000000 region. */
-    if ( (vl3tab[3] & _PAGE_PRESENT) == 0 )
-    {
-        alloc_pt(l2tab, vl2tab);
-        vl3tab[3] = l2tab | L3_PROT;
-    }
-
-    munmap(vl1tab, PAGE_SIZE);
-    munmap(vl2tab, PAGE_SIZE);
-    munmap(vl3tab, PAGE_SIZE);
-    return 0;
-
- error_out:
-    if (vl1tab)
-        munmap(vl1tab, PAGE_SIZE);
-    if (vl2tab)
-        munmap(vl2tab, PAGE_SIZE);
-    if (vl3tab)
-        munmap(vl3tab, PAGE_SIZE);
-    return -1;
-}
-
-#endif
-
-#if defined(__x86_64__)
-
-static int setup_pg_tables_64(int xc_handle, uint32_t dom,
-                              vcpu_guest_context_t *ctxt,
-                              unsigned long dsi_v_start,
-                              unsigned long v_end,
-                              xen_pfn_t *page_array,
-                              unsigned long vpt_start,
-                              unsigned long vpt_end,
-                              int shadow_mode_enabled)
-{
-    l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
-    l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
-    l3_pgentry_t *vl3tab=NULL, *vl3e=NULL;
-    l4_pgentry_t *vl4tab=NULL, *vl4e=NULL;
-    unsigned long l2tab = 0;
-    unsigned long l1tab = 0;
-    unsigned long l3tab = 0;
-    unsigned long l4tab = 0;
-    unsigned long ppt_alloc;
-    unsigned long count;
-
-    /* First allocate page for page dir. */
-    ppt_alloc = (vpt_start - dsi_v_start) >> PAGE_SHIFT;
-    alloc_pt(l4tab, vl4tab);
-    vl4e = &vl4tab[l4_table_offset(dsi_v_start)];
-    ctxt->ctrlreg[3] = xen_pfn_to_cr3(l4tab >> PAGE_SHIFT);
-
-    for ( count = 0; count < ((v_end-dsi_v_start)>>PAGE_SHIFT); count++)
-    {
-        if ( !((unsigned long)vl1e & (PAGE_SIZE-1)) )
-        {
-            alloc_pt(l1tab, vl1tab);
-
-            if ( !((unsigned long)vl2e & (PAGE_SIZE-1)) )
-            {
-                alloc_pt(l2tab, vl2tab);
-                if ( !((unsigned long)vl3e & (PAGE_SIZE-1)) )
-                {
-                    alloc_pt(l3tab, vl3tab);
-                    vl3e = &vl3tab[l3_table_offset(dsi_v_start + 
(count<<PAGE_SHIFT))];
-                    *vl4e++ = l3tab | L4_PROT;
-                }
-                vl2e = &vl2tab[l2_table_offset(dsi_v_start + 
(count<<PAGE_SHIFT))];
-                *vl3e++ = l2tab | L3_PROT;
-            }
-            vl1e = &vl1tab[l1_table_offset(dsi_v_start + (count<<PAGE_SHIFT))];
-            *vl2e++ = l1tab | L2_PROT;
-        }
-
-        *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
-
-        if ( !shadow_mode_enabled )
-            if ( (count >= ((vpt_start-dsi_v_start)>>PAGE_SHIFT)) &&
-                 (count <  ((vpt_end  -dsi_v_start)>>PAGE_SHIFT)) )
-                *vl1e &= ~_PAGE_RW;
-
-        vl1e++;
-    }
-
-    munmap(vl1tab, PAGE_SIZE);
-    munmap(vl2tab, PAGE_SIZE);
-    munmap(vl3tab, PAGE_SIZE);
-    munmap(vl4tab, PAGE_SIZE);
-    return 0;
-
- error_out:
-    if (vl1tab)
-        munmap(vl1tab, PAGE_SIZE);
-    if (vl2tab)
-        munmap(vl2tab, PAGE_SIZE);
-    if (vl3tab)
-        munmap(vl3tab, PAGE_SIZE);
-    if (vl4tab)
-        munmap(vl4tab, PAGE_SIZE);
-    return -1;
-}
-#endif
-
-#ifdef __ia64__
-static int setup_guest(int xc_handle,
-                       uint32_t dom,
-                       const char *image, unsigned long image_size,
-                       struct initrd_info *initrd,
-                       unsigned long nr_pages,
-                       unsigned long *pvsi, unsigned long *pvke,
-                       unsigned long *pvss, vcpu_guest_context_t *ctxt,
-                       const char *cmdline,
-                       unsigned long shared_info_frame,
-                       unsigned long flags,
-                       unsigned int store_evtchn, unsigned long *store_mfn,
-                       unsigned int console_evtchn, unsigned long *console_mfn,
-                       uint32_t required_features[XENFEAT_NR_SUBMAPS])
-{
-    xen_pfn_t *page_array = NULL;
-    struct load_funcs load_funcs;
-    struct domain_setup_info dsi;
-    unsigned long vinitrd_start;
-    unsigned long vinitrd_end;
-    unsigned long v_end;
-    unsigned long start_page, pgnr;
-    start_info_t *start_info;
-    unsigned long start_info_mpa;
-    struct xen_ia64_boot_param *bp;
-    shared_info_t *shared_info;
-    int i;
-    DECLARE_DOMCTL;
-    int rc;
-
-    rc = probeimageformat(image, image_size, &load_funcs);
-    if ( rc != 0 )
-        goto error_out;
-
-    memset(&dsi, 0, sizeof(struct domain_setup_info));
-
-    rc = (load_funcs.parseimage)(image, image_size, &dsi);
-    if ( rc != 0 )
-        goto error_out;
-
-    if ( (page_array = malloc(nr_pages * sizeof(xen_pfn_t))) == NULL )
-    {
-        PERROR("Could not allocate memory");
-        goto error_out;
-    }
-    for ( i = 0; i < nr_pages; i++ )
-        page_array[i] = i;
-    if ( xc_domain_memory_populate_physmap(xc_handle, dom, nr_pages,
-                                           0, 0, page_array) )
-    {
-        PERROR("Could not allocate memory for PV guest.\n");
-        goto error_out;
-    }
-
-    dsi.v_start    = round_pgdown(dsi.v_start);
-    vinitrd_start  = round_pgup(dsi.v_end);
-    start_info_mpa = (nr_pages - 3) << PAGE_SHIFT;
-    *pvke          = dsi.v_kernentry;
-
-    /* Build firmware.  */
-    memset(&domctl.u.arch_setup, 0, sizeof(domctl.u.arch_setup));
-    domctl.u.arch_setup.flags = 0;
-    domctl.u.arch_setup.bp = start_info_mpa + sizeof (start_info_t);
-    domctl.u.arch_setup.maxmem = (nr_pages - 3) << PAGE_SHIFT;
-    domctl.cmd = XEN_DOMCTL_arch_setup;
-    domctl.domain = (domid_t)dom;
-    if ( xc_domctl(xc_handle, &domctl) )
-        goto error_out;
-
-    start_page = dsi.v_start >> PAGE_SHIFT;
-    /* in order to get initrd->len, we need to load initrd image at first */
-    if ( load_initrd(xc_handle, dom, initrd,
-                     vinitrd_start - dsi.v_start, page_array + start_page) )
-        goto error_out;
-
-    vinitrd_end    = vinitrd_start + initrd->len;
-    v_end          = round_pgup(vinitrd_end);
-    pgnr = (v_end - dsi.v_start) >> PAGE_SHIFT;
-    if ( pgnr > nr_pages )
-    {
-        PERROR("too small memory is specified. "
-               "At least %ld kb is necessary.\n",
-               pgnr << (PAGE_SHIFT - 10));
-    }
-
-    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));
-    IPRINTF(" ENTRY ADDRESS: %p\n", _p(dsi.v_kernentry));
-
-    (load_funcs.loadimage)(image, image_size, xc_handle, dom,
-                           page_array + start_page, &dsi);
-
-    *store_mfn = page_array[nr_pages - 2]; //XXX
-    *console_mfn = page_array[nr_pages - 1]; //XXX
-    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[nr_pages - 3], nr_pages - 3,
-           *store_mfn,    nr_pages - 2,
-           *console_mfn,  nr_pages - 1);
-
-    start_info = xc_map_foreign_range(
-        xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
-        page_array[nr_pages - 3]);
-    if ( start_info == NULL )
-        goto error_out;
-
-    memset(start_info, 0, sizeof(*start_info));
-    rc = xc_version(xc_handle, XENVER_version, NULL);
-    sprintf(start_info->magic, "xen-%i.%i-ia64", rc >> 16, rc & (0xFFFF));
-    start_info->flags        = flags;
-    start_info->store_mfn    = nr_pages - 2;
-    start_info->store_evtchn = store_evtchn;
-    start_info->console.domU.mfn   = nr_pages - 1;
-    start_info->console.domU.evtchn = console_evtchn;
-    start_info->nr_pages       = nr_pages; // FIXME?: nr_pages - 2 ????
-
-    bp = (struct xen_ia64_boot_param *)(start_info + 1);
-    bp->command_line = start_info_mpa + offsetof(start_info_t, cmd_line);
-    if ( cmdline != NULL )
-    {
-        strncpy((char *)start_info->cmd_line, cmdline, MAX_GUEST_CMDLINE);
-        start_info->cmd_line[MAX_GUEST_CMDLINE - 1] = 0;
-    }
-    if ( initrd->len != 0 )
-    {
-        bp->initrd_start    = vinitrd_start;
-        bp->initrd_size     = initrd->len;
-    }
-    ctxt->user_regs.r28 = start_info_mpa + sizeof (start_info_t);
-    munmap(start_info, PAGE_SIZE);
-
-    /*
-     * shared_info is assiged into guest pseudo physical address space
-     * by XEN_DOMCTL_arch_setup. shared_info_frame is stale value until that.
-     * So passed shared_info_frame is stale. obtain the right value here.
-     */
-    domctl.cmd = XEN_DOMCTL_getdomaininfo;
-    domctl.domain = (domid_t)dom;
-    if ( (xc_domctl(xc_handle, &domctl) < 0) ||
-         ((uint16_t)domctl.domain != dom) )
-    {
-        PERROR("Could not get info on domain");
-        goto error_out;
-    }
-    shared_info_frame = domctl.u.getdomaininfo.shared_info_frame;
-
-    /* shared_info page starts its life empty. */
-    shared_info = xc_map_foreign_range(
-        xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, shared_info_frame);
-    printf("shared_info = %p frame=%lx\n",
-           shared_info, shared_info_frame);
-    //memset(shared_info, 0, PAGE_SIZE);
-    /* Mask all upcalls... */
-    for ( i = 0; i < MAX_VIRT_CPUS; i++ )
-        shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
-    shared_info->arch.start_info_pfn = nr_pages - 3;
-
-    munmap(shared_info, PAGE_SIZE);
-    free(page_array);
-    return 0;
-
- error_out:
-    free(page_array);
-    return -1;
-}
-#else /* x86 */
-
-/* Check if the platform supports the guest kernel format */
-static int compat_check(int xc_handle, struct domain_setup_info *dsi)
-{
-    xen_capabilities_info_t xen_caps = "";
-
-    if (xc_version(xc_handle, XENVER_capabilities, &xen_caps) != 0) {
-        xc_set_error(XC_INVALID_KERNEL,
-                     "Cannot determine host capabilities.");
-        return 0;
-    }
-
-#ifndef __x86_64__//temp
-    if (strstr(xen_caps, "xen-3.0-x86_32p")) {
-        if (dsi->pae_kernel == PAEKERN_bimodal) {
-            dsi->pae_kernel = PAEKERN_extended_cr3;
-        } else if (dsi->pae_kernel == PAEKERN_no) {
-            xc_set_error(XC_INVALID_KERNEL,
-                         "Non PAE-kernel on PAE host.");
-            return 0;
-        }
-    } else {
-        if (dsi->pae_kernel == PAEKERN_bimodal) {
-            dsi->pae_kernel = PAEKERN_no;
-        } else if (dsi->pae_kernel != PAEKERN_no) {
-            xc_set_error(XC_INVALID_KERNEL,
-                         "PAE-kernel on non-PAE host.");
-            return 0;
-        }
-    }
-#endif
-
-    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,
-                       const char *image, unsigned long image_size,
-                       struct initrd_info *initrd,
-                       unsigned long nr_pages,
-                       unsigned long *pvsi, unsigned long *pvke,
-                       unsigned long *pvss, vcpu_guest_context_t *ctxt,
-                       const char *cmdline,
-                       unsigned long shared_info_frame,
-                       unsigned long flags,
-                       unsigned int store_evtchn, unsigned long *store_mfn,
-                       unsigned int console_evtchn, unsigned long *console_mfn,
-                       uint32_t required_features[XENFEAT_NR_SUBMAPS])
-{
-    xen_pfn_t *page_array = NULL;
-    unsigned long count, i;
-    unsigned long long hypercall_page;
-    int hypercall_page_defined;
-    start_info_t *start_info;
-    shared_info_t *shared_info;
-    const char *p;
-    DECLARE_DOMCTL;
-    int rc;
-
-    unsigned long nr_pt_pages;
-    unsigned long physmap_pfn;
-    xen_pfn_t *physmap, *physmap_e;
-
-    struct load_funcs load_funcs;
-    struct domain_setup_info dsi;
-    unsigned long vinitrd_start;
-    unsigned long vphysmap_start;
-    unsigned long vstartinfo_start;
-    unsigned long vstoreinfo_start;
-    unsigned long vconsole_start;
-    unsigned long vsharedinfo_start = 0; /* XXX gcc */
-    unsigned long vstack_start;
-    unsigned long vstack_end;
-    unsigned long vpt_start;
-    unsigned long vpt_end;
-    unsigned long v_end;
-    unsigned long guest_store_mfn, guest_console_mfn, guest_shared_info_mfn;
-    unsigned long shadow_mode_enabled;
-    uint32_t supported_features[XENFEAT_NR_SUBMAPS] = { 0, };
-
-    rc = probeimageformat(image, image_size, &load_funcs);
-    if ( rc != 0 )
-        goto error_out;
-
-    memset(&dsi, 0, sizeof(struct domain_setup_info));
-
-    rc = (load_funcs.parseimage)(image, image_size, &dsi);
-    if ( rc != 0 )
-        goto error_out;
-
-    if ( (dsi.v_start & (PAGE_SIZE-1)) != 0 )
-    {
-        PERROR("Guest OS must load to a page boundary.");
-        goto error_out;
-    }
-
-    if ( !compat_check(xc_handle, &dsi) )
-        goto error_out;
-
-    /* Parse and validate kernel features. */
-    if ( (p = xen_elfnote_string(&dsi, XEN_ELFNOTE_FEATURES)) != NULL )
-    {
-        if ( !parse_features(p, supported_features, required_features) )
-        {
-            ERROR("Failed to parse guest kernel features.");
-            goto error_out;
-        }
-
-        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] )
-        {
-            ERROR("Guest kernel does not support a required feature.");
-            goto error_out;
-        }
-    }
-
-    shadow_mode_enabled = test_feature_bit(XENFEAT_auto_translated_physmap,
-                                           required_features);
-
-    if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
-    {
-        PERROR("Could not allocate memory");
-        goto error_out;
-    }
-
-    for ( i = 0; i < nr_pages; i++ )
-        page_array[i] = i;
-
-    if ( xc_domain_memory_populate_physmap(xc_handle, dom, nr_pages,
-                                           0, 0, page_array) )
-    {
-        PERROR("Could not allocate memory for PV guest.\n");
-        goto error_out;
-    }
-
-
-    if ( shadow_mode_enabled )
-    {
-        /*
-         * Enable shadow translate mode. This must happen after
-         * populate physmap because the p2m reservation is based on
-         * the domain's current memory allocation.
-         */
-        if ( xc_shadow_control(xc_handle, dom,
-                           XEN_DOMCTL_SHADOW_OP_ENABLE_TRANSLATE,
-                           NULL, 0, NULL, 0, NULL) < 0 )
-        {
-            PERROR("Could not enable translation mode");
-            goto error_out;
-        }
-
-        /* Reinitialise the gpfn->gmfn array. */
-        for ( i = 0; i < nr_pages; i++ )
-            page_array[i] = i;
-    }
-
-    rc = (load_funcs.loadimage)(image, image_size,
-                           xc_handle, dom, page_array,
-                           &dsi);
-    if ( rc != 0 )
-        goto error_out;
-
-    /*
-     * Why do we need this? The number of page-table frames depends on the
-     * size of the bootstrap address space. But the size of the address space
-     * depends on the number of page-table frames (since each one is mapped
-     * read-only). We have a pair of simultaneous equations in two unknowns,
-     * 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;
-    if ( load_initrd(xc_handle, dom, initrd,
-                     vinitrd_start - dsi.v_start, page_array) )
-        goto error_out;
-    if ( !increment_ulong(&v_end, round_pgup(initrd->len)) )
-        goto error_out;
-
-    vphysmap_start = v_end;
-    if ( !increment_ulong(&v_end, round_pgup(nr_pages * sizeof(long))) )
-        goto error_out;
-    vstartinfo_start = v_end;
-    if ( !increment_ulong(&v_end, PAGE_SIZE) )
-        goto error_out;
-    vstoreinfo_start = v_end;
-    if ( !increment_ulong(&v_end, PAGE_SIZE) )
-        goto error_out;
-    vconsole_start = v_end;
-    if ( !increment_ulong(&v_end, PAGE_SIZE) )
-        goto error_out;
-    if ( shadow_mode_enabled ) {
-        vsharedinfo_start = v_end;
-        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_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) )
-        {
-            /* Add extra 4MB to get >= 512kB padding. */
-            if ( !increment_ulong(&v_end, 1UL << 22) )
-                goto error_out;
-        }
-
-#define NR(_l,_h,_s)                                                    \
-    (((((unsigned long)(_h) + ((1UL<<(_s))-1)) & ~((1UL<<(_s))-1)) -    \
-    ((unsigned long)(_l) & ~((1UL<<(_s))-1))) >> (_s))
-#if defined(__i386__)
-        if ( dsi.pae_kernel != PAEKERN_no )
-        {
-            if ( (1 + /* # L3 */
-                  NR(dsi.v_start, v_end, L3_PAGETABLE_SHIFT_PAE) + /* # L2 */
-                  NR(dsi.v_start, v_end, L2_PAGETABLE_SHIFT_PAE) + /* # L1 */
-                  /* Include a fourth mid-level page directory for Xen. */
-                  (v_end <= (3 << L3_PAGETABLE_SHIFT_PAE)))
-                  <= nr_pt_pages )
-                break;
-        }
-        else
-        {
-            if ( (1 + /* # L2 */
-                  NR(dsi.v_start, v_end, L2_PAGETABLE_SHIFT)) /* # L1 */
-                 <= nr_pt_pages )
-                break;
-        }
-#elif defined(__x86_64__)
-        if ( (1 + /* # L4 */
-              NR(dsi.v_start, v_end, L4_PAGETABLE_SHIFT) + /* # L3 */
-              NR(dsi.v_start, v_end, L3_PAGETABLE_SHIFT) + /* # L2 */
-              NR(dsi.v_start, v_end, L2_PAGETABLE_SHIFT))  /* # L1 */
-             <= nr_pt_pages )
-            break;
-#endif
-    }
-
-    IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n");
-    IPRINTF(" Loaded kernel:    %p->%p\n", _p(dsi.v_kernstart),
-           _p(dsi.v_kernend));
-    if ( initrd->len )
-        IPRINTF(" Initial ramdisk:  %p->%p\n", _p(vinitrd_start),
-               _p(vinitrd_start + initrd->len));
-    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 )
-        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 )
-    {
-        PERROR("Initial guest OS requires too much space\n"
-               "(%pMB is greater than %luMB limit)\n",
-               _p((v_end-dsi.v_start)>>20), nr_pages>>(20-PAGE_SHIFT));
-        goto error_out;
-    }
-
-#if defined(__i386__)
-    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, dsi.pae_kernel);
-    else
-        rc = setup_pg_tables(xc_handle, dom, ctxt,
-                             dsi.v_start, v_end,
-                             page_array, vpt_start, vpt_end,
-                             shadow_mode_enabled);
-#endif
-#if defined(__x86_64__)
-    rc = setup_pg_tables_64(xc_handle, dom, ctxt,
-                            dsi.v_start, v_end,
-                            page_array, vpt_start, vpt_end,
-                            shadow_mode_enabled);
-#endif
-    if ( rc != 0 )
-        goto error_out;
-
-    /*
-     * Pin down l2tab addr as page dir page - causes hypervisor to provide
-     * correct protection for the page
-     */
-    if ( !shadow_mode_enabled )
-    {
-#if defined(__i386__)
-        if ( dsi.pae_kernel != PAEKERN_no )
-        {
-            if ( pin_table(xc_handle, MMUEXT_PIN_L3_TABLE,
-                           xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) )
-                goto error_out;
-        }
-        else
-        {
-            if ( pin_table(xc_handle, MMUEXT_PIN_L2_TABLE,
-                           xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) )
-                goto error_out;
-        }
-#elif defined(__x86_64__)
-        /*
-         * Pin down l4tab addr as page dir page - causes hypervisor to  provide
-         * correct protection for the page
-         */
-        if ( pin_table(xc_handle, MMUEXT_PIN_L4_TABLE,
-                       xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) )
-            goto error_out;
-#endif
-    }
-
-    /* Write the phys->machine table entries (machine->phys already done). */
-    physmap_pfn = (vphysmap_start - dsi.v_start) >> PAGE_SHIFT;
-    physmap = physmap_e = xc_map_foreign_range(
-        xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
-        page_array[physmap_pfn++]);
-    for ( count = 0; count < nr_pages; count++ )
-    {
-        *physmap_e++ = page_array[count];
-        if ( ((unsigned long)physmap_e & (PAGE_SIZE-1)) == 0 )
-        {
-            munmap(physmap, PAGE_SIZE);
-            physmap = physmap_e = xc_map_foreign_range(
-                xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
-                page_array[physmap_pfn++]);
-        }
-    }
-    munmap(physmap, PAGE_SIZE);
-
-    if ( shadow_mode_enabled )
-    {
-        struct xen_add_to_physmap xatp;
-
-        guest_shared_info_mfn = (vsharedinfo_start-dsi.v_start) >> PAGE_SHIFT;
-
-        /* Map shared info frame into guest physmap. */
-        xatp.domid = dom;
-        xatp.space = XENMAPSPACE_shared_info;
-        xatp.idx   = 0;
-        xatp.gpfn  = guest_shared_info_mfn;
-        rc = xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp);
-        if ( rc != 0 )
-        {
-            PERROR("Cannot map shared info pfn");
-            goto error_out;
-        }
-
-        /* Map grant table frames into guest physmap. */
-        for ( i = 0; ; i++ )
-        {
-            xatp.domid = dom;
-            xatp.space = XENMAPSPACE_grant_table;
-            xatp.idx   = i;
-            xatp.gpfn  = nr_pages + i;
-            rc = xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp);
-            if ( rc != 0 )
-            {
-                if ( errno == EINVAL )
-                    break; /* done all grant tables */
-                PERROR("Cannot map grant table pfn");
-                goto error_out;
-            }
-        }
-    }
-    else
-    {
-        guest_shared_info_mfn = shared_info_frame;
-    }
-
-    *store_mfn = page_array[(vstoreinfo_start-dsi.v_start) >> PAGE_SHIFT];
-    *console_mfn = page_array[(vconsole_start-dsi.v_start) >> PAGE_SHIFT];
-    if ( xc_clear_domain_page(xc_handle, dom, *store_mfn) ||
-         xc_clear_domain_page(xc_handle, dom, *console_mfn) )
-        goto error_out;
-    if ( shadow_mode_enabled )
-    {
-        guest_store_mfn = (vstoreinfo_start-dsi.v_start) >> PAGE_SHIFT;
-        guest_console_mfn = (vconsole_start-dsi.v_start) >> PAGE_SHIFT;
-    }
-    else
-    {
-        guest_store_mfn = *store_mfn;
-        guest_console_mfn = *console_mfn;
-    }
-
-    start_info = xc_map_foreign_range(
-        xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
-        page_array[(vstartinfo_start-dsi.v_start)>>PAGE_SHIFT]);
-    /*shared_info, start_info */
-    memset(start_info, 0, sizeof(*start_info));
-    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 != PAEKERN_no) ? "p" : "");
-    start_info->nr_pages     = nr_pages;
-    start_info->shared_info  = guest_shared_info_mfn << PAGE_SHIFT;
-    start_info->flags        = flags;
-    start_info->pt_base      = vpt_start;
-    start_info->nr_pt_frames = nr_pt_pages;
-    start_info->mfn_list     = vphysmap_start;
-    start_info->store_mfn    = guest_store_mfn;
-    start_info->store_evtchn = store_evtchn;
-    start_info->console.domU.mfn   = guest_console_mfn;
-    start_info->console.domU.evtchn = console_evtchn;
-    if ( initrd->len != 0 )
-    {
-        start_info->mod_start    = vinitrd_start;
-        start_info->mod_len      = initrd->len;
-    }
-    if ( cmdline != NULL )
-    {
-        strncpy((char *)start_info->cmd_line, cmdline, MAX_GUEST_CMDLINE);
-        start_info->cmd_line[MAX_GUEST_CMDLINE-1] = '\0';
-    }
-    munmap(start_info, PAGE_SIZE);
-
-    /* shared_info page starts its life empty. */
-    shared_info = xc_map_foreign_range(
-        xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, shared_info_frame);
-    memset(shared_info, 0, PAGE_SIZE);
-    /* Mask all upcalls... */
-    for ( i = 0; i < MAX_VIRT_CPUS; i++ )
-        shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
-
-    munmap(shared_info, PAGE_SIZE);
-
-    hypercall_page = xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE,
-                                         &hypercall_page_defined);
-    if ( hypercall_page_defined )
-    {
-        unsigned long long pfn = (hypercall_page - dsi.v_start) >> PAGE_SHIFT;
-        if ( pfn >= nr_pages )
-            goto error_out;
-        domctl.domain = (domid_t)dom;
-        domctl.u.hypercall_init.gmfn = page_array[pfn];
-        domctl.cmd = XEN_DOMCTL_hypercall_init;
-        if ( xc_domctl(xc_handle, &domctl) )
-            goto error_out;
-    }
-
-    free(page_array);
-
-    *pvsi = vstartinfo_start;
-    *pvss = vstack_start;
-    *pvke = dsi.v_kernentry;
-
-    return 0;
-
- error_out:
-    free(page_array);
-    return -1;
-}
-#endif
-
-static int xc_linux_build_internal(int xc_handle,
-                                   uint32_t domid,
-                                   unsigned int mem_mb,
-                                   const char *image,
-                                   unsigned long image_size,
-                                   struct initrd_info *initrd,
-                                   const char *cmdline,
-                                   const char *features,
-                                   unsigned long flags,
-                                   unsigned int store_evtchn,
-                                   unsigned long *store_mfn,
-                                   unsigned int console_evtchn,
-                                   unsigned long *console_mfn)
-{
-    struct xen_domctl launch_domctl;
-    DECLARE_DOMCTL;
-    int rc;
-    struct vcpu_guest_context st_ctxt, *ctxt = &st_ctxt;
-    unsigned long vstartinfo_start, vkern_entry, vstack_start;
-    uint32_t      features_bitmap[XENFEAT_NR_SUBMAPS] = { 0, };
-
-    if ( features != NULL )
-    {
-        if ( !parse_features(features, features_bitmap, NULL) )
-        {
-            PERROR("Failed to parse configured features\n");
-            goto error_out;
-        }
-    }
-
-    memset(ctxt, 0, sizeof(*ctxt));
-
-    if ( lock_pages(ctxt, sizeof(*ctxt) ) )
-    {
-        PERROR("%s: ctxt lock failed", __func__);
-        return 1;
-    }
-
-    domctl.cmd = XEN_DOMCTL_getdomaininfo;
-    domctl.domain = (domid_t)domid;
-    if ( (xc_domctl(xc_handle, &domctl) < 0) ||
-         ((uint16_t)domctl.domain != domid) )
-    {
-        PERROR("Could not get info on domain");
-        goto error_out;
-    }
-
-    if ( setup_guest(xc_handle, domid, image, image_size,
-                     initrd,
-                     mem_mb << (20 - PAGE_SHIFT),
-                     &vstartinfo_start, &vkern_entry,
-                     &vstack_start, ctxt, cmdline,
-                     domctl.u.getdomaininfo.shared_info_frame,
-                     flags, store_evtchn, store_mfn,
-                     console_evtchn, console_mfn,
-                     features_bitmap) < 0 )
-    {
-        goto error_out;
-    }
-
-#ifdef __ia64__
-    /* based on new_thread in xen/arch/ia64/domain.c */
-    ctxt->user_regs.cr_iip = vkern_entry;
-    ctxt->user_regs.cr_ifs = 1UL << 63;
-    ctxt->user_regs.ar_fpsr = xc_ia64_fpsr_default();
-#else /* x86 */
-    /*
-     * Initial register values:
-     *  DS,ES,FS,GS = FLAT_KERNEL_DS
-     *       CS:EIP = FLAT_KERNEL_CS:start_pc
-     *       SS:ESP = FLAT_KERNEL_DS:start_stack
-     *          ESI = start_info
-     *  [EAX,EBX,ECX,EDX,EDI,EBP are zero]
-     *       EFLAGS = IF | 2 (bit 1 is reserved and should always be 1)
-     */
-    ctxt->user_regs.ds = FLAT_KERNEL_DS;
-    ctxt->user_regs.es = FLAT_KERNEL_DS;
-    ctxt->user_regs.fs = FLAT_KERNEL_DS;
-    ctxt->user_regs.gs = FLAT_KERNEL_DS;
-    ctxt->user_regs.ss = FLAT_KERNEL_SS;
-    ctxt->user_regs.cs = FLAT_KERNEL_CS;
-    ctxt->user_regs.eip = vkern_entry;
-    ctxt->user_regs.esp = vstack_start + PAGE_SIZE;
-    ctxt->user_regs.esi = vstartinfo_start;
-    ctxt->user_regs.eflags = 1 << 9; /* Interrupt Enable */
-
-    ctxt->flags = VGCF_IN_KERNEL;
-
-    ctxt->kernel_ss = ctxt->user_regs.ss;
-    ctxt->kernel_sp = ctxt->user_regs.esp;
-#endif /* x86 */
-
-    memset(&launch_domctl, 0, sizeof(launch_domctl));
-
-    launch_domctl.domain = (domid_t)domid;
-    launch_domctl.u.vcpucontext.vcpu   = 0;
-    set_xen_guest_handle(launch_domctl.u.vcpucontext.ctxt, ctxt);
-
-    launch_domctl.cmd = XEN_DOMCTL_setvcpucontext;
-    rc = xc_domctl(xc_handle, &launch_domctl);
-
-    return rc;
-
- error_out:
-    return -1;
-}
-
-int xc_linux_build_mem(int xc_handle,
-                       uint32_t domid,
-                       unsigned int mem_mb,
-                       const char *image_buffer,
-                       unsigned long image_size,
-                       const char *initrd,
-                       unsigned long initrd_len,
-                       const char *cmdline,
-                       const char *features,
-                       unsigned long flags,
-                       unsigned int store_evtchn,
-                       unsigned long *store_mfn,
-                       unsigned int console_evtchn,
-                       unsigned long *console_mfn)
-{
-    int            sts;
-    char          *img_buf;
-    unsigned long  img_len;
-    struct initrd_info initrd_info = { .type = INITRD_none };
-
-    /* A kernel buffer is required */
-    if ( (image_buffer == NULL) || (image_size == 0) )
-    {
-        ERROR("kernel image buffer not present");
-        return -1;
-    }
-
-    /* If it's gzipped, inflate it;  otherwise, use as is */
-    /* xc_inflate_buffer may return the same buffer pointer if */
-    /* the buffer is already inflated */
-    img_buf = xc_inflate_buffer(image_buffer, image_size, &img_len);
-    if ( img_buf == NULL )
-    {
-        ERROR("unable to inflate kernel image buffer");
-        return -1;
-    }
-
-    /* RAM disks are optional; if we get one, inflate it */
-    if ( initrd != NULL )
-    {
-        initrd_info.type = INITRD_mem;
-        initrd_info.u.mem_addr = xc_inflate_buffer(
-            initrd, initrd_len, &initrd_info.len);
-        if ( initrd_info.u.mem_addr == NULL )
-        {
-            ERROR("unable to inflate ram disk buffer");
-            sts = -1;
-            goto out;
-        }
-    }
-
-    sts = xc_linux_build_internal(xc_handle, domid, mem_mb, img_buf, img_len,
-                                  &initrd_info, cmdline, features, flags,
-                                  store_evtchn, store_mfn,
-                                  console_evtchn, console_mfn);
-
- out:
-    /* The inflation routines may pass back the same buffer so be */
-    /* sure that we have a buffer and that it's not the one passed in. */
-    /* Don't unnecessarily annoy/surprise/confound the caller */
-    if ( (img_buf != NULL) && (img_buf != image_buffer) )
-        free(img_buf);
-    if ( (initrd_info.u.mem_addr != NULL) &&
-         (initrd_info.u.mem_addr != initrd) )
-        free(initrd_info.u.mem_addr);
-
-    return sts;
-}
-
-int xc_linux_build(int xc_handle,
-                   uint32_t domid,
-                   unsigned int mem_mb,
-                   const char *image_name,
-                   const char *initrd_name,
-                   const char *cmdline,
-                   const char *features,
-                   unsigned long flags,
-                   unsigned int store_evtchn,
-                   unsigned long *store_mfn,
-                   unsigned int console_evtchn,
-                   unsigned long *console_mfn)
-{
-    char *image = NULL;
-    unsigned long image_size;
-    struct initrd_info initrd_info = { .type = INITRD_none };
-    int fd = -1, sts = -1;
-
-    if ( (image_name == NULL) ||
-         ((image = xc_read_image(image_name, &image_size)) == NULL ))
-        return -1;
-
-    if ( (initrd_name != NULL) && (strlen(initrd_name) != 0) )
-    {
-        initrd_info.type = INITRD_file;
-
-        if ( (fd = open(initrd_name, O_RDONLY)) < 0 )
-        {
-            PERROR("Could not open the initial ramdisk image");
-            goto error_out;
-        }
-
-        if ( (initrd_info.u.file_handle = gzdopen(fd, "rb")) == NULL )
-        {
-            PERROR("Could not allocate decompression state for initrd");
-            goto error_out;
-        }
-    }
-
-    sts = xc_linux_build_internal(xc_handle, domid, mem_mb, image, image_size,
-                                  &initrd_info, cmdline, features, flags,
-                                  store_evtchn, store_mfn,
-                                  console_evtchn, console_mfn);
-
- error_out:
-    free(image);
-    if ( initrd_info.type == INITRD_file && initrd_info.u.file_handle )
-        gzclose(initrd_info.u.file_handle);
-    else if ( fd >= 0 )
-        close(fd);
-
-    return sts;
-}
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
diff -r 04c23c1ef888 -r d907467f08cd tools/libxc/xc_linux_restore.c
--- a/tools/libxc/xc_linux_restore.c    Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libxc/xc_linux_restore.c    Tue Feb 20 12:58:22 2007 -0700
@@ -82,7 +82,7 @@ static int uncanonicalize_pagetable(int 
         if(!(pte & _PAGE_PRESENT))
             continue; 
         
-        pfn = (pte >> PAGE_SHIFT) & 0xffffffff;
+        pfn = (pte >> PAGE_SHIFT) & MFN_MASK_X86;
         
         if(pfn >= max_pfn) {
             /* This "page table page" is probably not one; bail. */
@@ -120,12 +120,12 @@ static int uncanonicalize_pagetable(int 
         if(!(pte & _PAGE_PRESENT))
             continue;
         
-        pfn = (pte >> PAGE_SHIFT) & 0xffffffff;
+        pfn = (pte >> PAGE_SHIFT) & MFN_MASK_X86;
         
         if(p2m[pfn] == INVALID_P2M_ENTRY)
             p2m[pfn] = p2m_batch[nr_mfns++];
 
-        pte &= 0xffffff0000000fffULL;
+        pte &= ~MADDR_MASK_X86;
         pte |= (uint64_t)p2m[pfn] << PAGE_SHIFT;
 
         if(pt_levels == 2)
diff -r 04c23c1ef888 -r d907467f08cd tools/libxc/xc_linux_save.c
--- a/tools/libxc/xc_linux_save.c       Sun Feb 18 16:13:13 2007 -0700
+++ b/tools/libxc/xc_linux_save.c       Tue Feb 20 12:58:22 2007 -0700
@@ -495,7 +495,7 @@ static int canonicalize_pagetable(unsign
         hstart = (hvirt_start >> L2_PAGETABLE_SHIFT_PAE) & 0x1ff;
         he = ((const uint64_t *) spage)[hstart];
 
-        if ( ((he >> PAGE_SHIFT) & 0x0fffffff) == m2p_mfn0 ) {
+        if ( ((he >> PAGE_SHIFT) & MFN_MASK_X86) == m2p_mfn0 ) {
             /* hvirt starts with xen stuff... */
             xen_start = hstart;
         } else if ( hvirt_start != 0xf5800000 ) {
@@ -503,7 +503,7 @@ static int canonicalize_pagetable(unsign
             hstart = (0xf5800000 >> L2_PAGETABLE_SHIFT_PAE) & 0x1ff;
             he = ((const uint64_t *) spage)[hstart];
 
-            if( ((he >> PAGE_SHIFT) & 0x0fffffff) == m2p_mfn0 )
+            if( ((he >> PAGE_SHIFT) & MFN_MASK_X86) == m2p_mfn0 )
                 xen_start = hstart;
         }
     }
@@ -532,7 +532,7 @@ static int canonicalize_pagetable(unsign
 
         if (pte & _PAGE_PRESENT) {
 
-            mfn = (pte >> PAGE_SHIFT) & 0xfffffff;
+            mfn = (pte >> PAGE_SHIFT) & MFN_MASK_X86;
             if (!MFN_IS_IN_PSEUDOPHYS_MAP(mfn)) {
                 /* This will happen if the type info is stale which
                    is quite feasible under live migration */
@@ -541,7 +541,7 @@ static int canonicalize_pagetable(unsign
             } else
                 pfn = mfn_to_pfn(mfn);
 
-            pte &= 0xffffff0000000fffULL;
+            pte &= ~MADDR_MASK_X86;
             pte |= (uint64_t)pfn << PAGE_SHIFT;
         }
 
diff -r 04c23c1ef888 -r d907467f08cd tools/libxc/xc_load_bin.c
--- a/tools/libxc/xc_load_bin.c Sun Feb 18 16:13:13 2007 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,306 +0,0 @@
-/******************************************************************************
- * xc_bin_load.c
- *
- * Based on xc_elf_load.c
- *
- * Loads simple binary images. It's like a .COM file in MS-DOS. No headers are
- * present. The only requirement is that it must have a xen_bin_image table
- * somewhere in the first 8192 bytes, starting on a 32-bit aligned address.
- * Those familiar with the multiboot specification should recognize this, it's
- * (almost) the same as the multiboot header.
- * The layout of the xen_bin_image table is:
- *
- * Offset Type Name          Note
- * 0      uint32_t  magic         required
- * 4      uint32_t  flags         required
- * 8      uint32_t  checksum      required
- * 12     uint32_t  header_addr   required
- * 16     uint32_t  load_addr     required
- * 20     uint32_t  load_end_addr required
- * 24     uint32_t  bss_end_addr  required
- * 28     uint32_t  entry_addr    required
- *
- * - magic
- *   Magic number identifying the table. For images to be loaded by Xen 3, the
- *   magic value is 0x336ec578 ("xEn3" with the 0x80 bit of the "E" set).
- * - flags
- *   bit 0: indicates whether the image needs to be loaded on a page boundary
- *   bit 1: reserved, must be 0 (the multiboot spec uses this bit to indicate
- *          that memory info should be passed to the image)
- *   bit 2: reserved, must be 0 (the multiboot spec uses this bit to indicate
- *          that the bootloader should pass video mode info to the image)
- *   bit 16: reserved, must be 1 (the multiboot spec uses this bit to indicate
- *           that the values in the fields header_addr - entry_addr are
- *           valid)
- *   All other bits should be set to 0.
- * - checksum
- *   When added to "magic" and "flags", the resulting value should be 0.
- * - header_addr
- *   Contains the virtual address corresponding to the beginning of the
- *   table - the memory location at which the magic value is supposed to be
- *   loaded. This field serves to synchronize the mapping between OS image
- *   offsets and virtual memory addresses.
- * - load_addr
- *   Contains the virtual address of the beginning of the text segment. The
- *   offset in the OS image file at which to start loading is defined by the
- *   offset at which the table was found, minus (header addr - load addr).
- *   load addr must be less than or equal to header addr.
- * - load_end_addr
- *   Contains the virtual address of the end of the data segment.
- *   (load_end_addr - load_addr) specifies how much data to load. This implies
- *   that the text and data segments must be consecutive in the OS image. If
- *   this field is zero, the domain builder assumes that the text and data
- *   segments occupy the whole OS image file.
- * - bss_end_addr
- *   Contains the virtual address of the end of the bss segment. The domain
- *   builder initializes this area to zero, and reserves the memory it occupies
- *   to avoid placing boot modules and other data relevant to the loaded image
- *   in that area. If this field is zero, the domain builder assumes that no 
bss
- *   segment is present.
- * - entry_addr
- *   The virtual address at which to start execution of the loaded image.
- *
- * Some of the field descriptions were copied from "The Multiboot
- * Specification", Copyright 1995, 96 Bryan Ford <baford@xxxxxxxxxxx>,
- * Erich Stefan Boleyn <erich@xxxxxxxx> Copyright 1999, 2000, 2001, 2002
- * Free Software Foundation, Inc.
- */
-
-#include "xg_private.h"
-#include <stdlib.h>
-
-#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
-#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
-
-#define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
-#define round_pgdown(_p)  ((_p)&PAGE_MASK)
-
-struct xen_bin_image_table
-{
-    unsigned long magic;
-    unsigned long flags;
-    unsigned long checksum;
-    unsigned long header_addr;
-    unsigned long load_addr;
-    unsigned long load_end_addr;
-    unsigned long bss_end_addr;
-    unsigned long entry_addr;
-};
-
-#define XEN_REACTOS_MAGIC3 0x336ec578
-
-#define XEN_REACTOS_FLAG_ALIGN4K     0x00000001
-#define XEN_REACTOS_FLAG_NEEDMEMINFO 0x00000002
-#define XEN_REACTOS_FLAG_NEEDVIDINFO 0x00000004
-#define XEN_REACTOS_FLAG_ADDRSVALID  0x00010000
-
-/* Flags we test for */
-#define FLAGS_MASK     ((~ 0) & (~ XEN_REACTOS_FLAG_ALIGN4K))
-#define FLAGS_REQUIRED XEN_REACTOS_FLAG_ADDRSVALID
-
-static const struct xen_bin_image_table *
-findtable(const char *image, unsigned long image_size);
-static int
-parsebinimage(
-    const char *image, unsigned long image_size,
-    struct domain_setup_info *dsi);
-static int
-loadbinimage(
-    const char *image, unsigned long image_size, int xch, uint32_t dom,
-    xen_pfn_t *parray, struct domain_setup_info *dsi);
-
-int probe_bin(const char *image,
-              unsigned long image_size,
-              struct load_funcs *load_funcs)
-{
-    if ( findtable(image, image_size) == NULL )
-        return -EINVAL;
-
-    load_funcs->parseimage = parsebinimage;
-    load_funcs->loadimage = loadbinimage;
-
-    return 0;
-}
-
-static const struct xen_bin_image_table *
-findtable(const char *image, unsigned long image_size)
-{
-    const struct xen_bin_image_table *table;
-    const unsigned long *probe_ptr;
-    unsigned probe_index;
-    unsigned probe_count;
-
-    /* Don't go outside the image */
-    if ( image_size < sizeof(struct xen_bin_image_table) )
-        return NULL;
-
-    probe_count = image_size;
-    /* Restrict to first 8k */
-    if ( probe_count > 8192 )
-        probe_count = 8192;
-    probe_count = (probe_count - sizeof(struct xen_bin_image_table)) /
-                  sizeof(unsigned long);
-
-    /* Search for the magic header */
-    probe_ptr = (const unsigned long *) image;
-    table = NULL;
-    for ( probe_index = 0; probe_index < probe_count; probe_index++ )
-    {
-        if ( XEN_REACTOS_MAGIC3 == *probe_ptr )
-        {
-            table = (const struct xen_bin_image_table *) probe_ptr;
-            /* Checksum correct? */
-            if ( 0 == table->magic + table->flags + table->checksum )
-            {
-                return table;
-            }
-        }
-        probe_ptr++;
-    }
-
-    return NULL;
-}
-
-static int parsebinimage(const char *image,
-                         unsigned long image_size,
-                         struct domain_setup_info *dsi)
-{
-    const struct xen_bin_image_table *image_info;
-    unsigned long start_addr;
-    unsigned long end_addr;
-
-    image_info = findtable(image, image_size);
-    if ( NULL == image_info )
-    {
-        ERROR("Image does not have a valid xen_bin_image_table table.");
-        return -EINVAL;
-    }
-
-    /* Check the flags */
-    if ( FLAGS_REQUIRED != (image_info->flags & FLAGS_MASK) )
-    {
-        ERROR("xen_bin_image_table flags required 0x%08x found 0x%08lx",
-              FLAGS_REQUIRED, image_info->flags & FLAGS_MASK);
-        return -EINVAL;
-    }
-
-    /* Sanity check on the addresses */
-    if ( image_info->header_addr < image_info->load_addr ||
-         ((const char *) image_info - image) <
-         (image_info->header_addr - image_info->load_addr) )
-    {
-        ERROR("Invalid header_addr.");
-        return -EINVAL;
-    }
-    start_addr = image_info->header_addr - ((const char *) image_info - image);
-    if ( 0 != image_info->load_end_addr &&
-         ( image_info->load_end_addr < image_info->load_end_addr ||
-           start_addr + image_size < image_info->load_end_addr ) )
-    {
-        ERROR("Invalid load_end_addr");
-        return -EINVAL;
-    }
-    end_addr = (0 == image_info->load_end_addr ? start_addr + image_size :
-                                                 image_info->load_end_addr);
-    if ( 0 != image_info->bss_end_addr &&
-         image_info->bss_end_addr < end_addr )
-    {
-        ERROR("Invalid bss_end_addr");
-        return -EINVAL;
-    }
-
-    dsi->v_start = image_info->load_addr;
-    if ( 0 != image_info->bss_end_addr )
-    {
-        dsi->v_end = image_info->bss_end_addr;
-    }
-    else if ( 0 != image_info->load_end_addr )
-    {
-        dsi->v_end = image_info->load_end_addr;
-    }
-    else
-    {
-        dsi->v_end = image_info->load_addr + image_size -
-                     (((const char *) image_info - image) -
-                      (image_info->header_addr - image_info->load_addr));
-    }
-    dsi->v_kernstart = dsi->v_start;
-    dsi->v_kernend = dsi->v_end;
-    dsi->v_kernentry = image_info->entry_addr;
-    dsi->__xen_guest_string = NULL;
-
-    return 0;
-}
-
-static int
-loadbinimage(
-    const char *image, unsigned long image_size, int xch, uint32_t dom,
-    xen_pfn_t *parray, struct domain_setup_info *dsi)
-{
-    unsigned long size;
-    char         *va;
-    unsigned long done, chunksz;
-    const struct xen_bin_image_table *image_info;
-
-    image_info = findtable(image, image_size);
-    if ( NULL == image_info )
-    {
-        ERROR("Image does not have a valid xen_bin_image_table table.");
-        return -EINVAL;
-    }
-
-    /* Determine image size */
-    if ( 0 == image_info->load_end_addr )
-    {
-        size = image_size  - (((const char *)image_info - image) -
-                              (image_info->header_addr -
-                               image_info->load_addr));
-    }
-    else
-    {
-        size = image_info->load_end_addr - image_info->load_addr;
-    }
-
-    /* It's possible that we need to skip the first part of the image */
-    image += ((const char *)image_info - image) -
-             (image_info->header_addr - image_info->load_addr);
-
-    for ( done = 0; done < size; done += chunksz )
-    {
-        va = xc_map_foreign_range(
-            xch, dom, PAGE_SIZE, PROT_WRITE, parray[done>>PAGE_SHIFT]);
-        chunksz = size - done;
-        if ( chunksz > PAGE_SIZE )
-            chunksz = PAGE_SIZE;
-        memcpy(va, image + done, chunksz);
-        munmap(va, PAGE_SIZE);
-    }
-
-    if ( 0 != image_info->bss_end_addr &&
-         image_info->load_addr + size < image_info->bss_end_addr )
-    {
-        size = image_info->bss_end_addr - image_info->load_addr;
-    }
-    for ( ; done < size; done += chunksz )
-    {
-        va = xc_map_foreign_range(
-            xch, dom, PAGE_SIZE, PROT_WRITE, parray[done>>PAGE_SHIFT]);
-        chunksz = size - done;
-        if ( chunksz > (PAGE_SIZE - (done & (PAGE_SIZE-1))) )
-            chunksz = PAGE_SIZE - (done & (PAGE_SIZE-1));
-        memset(va + (done & (PAGE_SIZE-1)), 0, chunksz);
-        munmap(va, PAGE_SIZE);
-    }
-
-    return 0;
-}
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
diff -r 04c23c1ef888 -r d907467f08cd tools/libxc/xc_load_elf.c
--- a/tools/libxc/xc_load_elf.c Sun Feb 18 16:13:13 2007 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,684 +0,0 @@
-/******************************************************************************
- * xc_elf_load.c
- */
-
-#include "xg_private.h"
-#include "xc_elf.h"
-#include <stdlib.h>
-#include <inttypes.h>
-
-#define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
-#define round_pgdown(_p)  ((_p)&PAGE_MASK)
-
-static int
-parseelfimage(
-    const char *image, unsigned long image_size,
-    struct domain_setup_info *dsi);
-static int
-loadelfimage(
-    const char *image, unsigned long image_size, int xch, uint32_t dom,
-    xen_pfn_t *parray, struct domain_setup_info *dsi);
-static int
-loadelfsymtab(
-    const char *image, int xch, uint32_t dom, xen_pfn_t *parray,
-    struct domain_setup_info *dsi);
-
-/*
- * Elf header attributes we require for each supported host platform.
- * These are checked in parseelfimage().
- */
-#if defined(__ia64__)
-#define ELFCLASS   ELFCLASS64
-#define ELFCLASS_DESC "64-bit"
-
-#define ELFDATA    ELFDATA2LSB
-#define ELFDATA_DESC "Little-Endian"
-
-#define ELFMACHINE EM_IA_64
-#define ELFMACHINE_DESC "ia64"
-
-
-#elif defined(__i386__)
-#define ELFCLASS   ELFCLASS32
-#define ELFCLASS_DESC "32-bit"
-
-#define ELFDATA    ELFDATA2LSB
-#define ELFDATA_DESC "Little-Endian"
-
-#define ELFMACHINE EM_386
-#define ELFMACHINE_DESC "i386"
-
-
-#elif defined(__x86_64__)
-#define ELFCLASS   ELFCLASS64
-#define ELFCLASS_DESC "64-bit"
-
-#define ELFDATA    ELFDATA2LSB
-#define ELFDATA_DESC "Little-Endian"
-
-#define ELFMACHINE EM_X86_64
-#define ELFMACHINE_DESC "x86_64"
-
-
-#elif defined(__powerpc__)
-#define ELFCLASS   ELFCLASS64
-#define ELFCLASS_DESC "64-bit"
-
-#define ELFDATA    ELFDATA2MSB
-#define ELFDATA_DESC "Big-Endian"
-
-#define ELFMACHINE EM_PPC64
-#define ELFMACHINE_DESC "ppc64"
-#endif
-
-int probe_elf(const char *image,
-              unsigned long image_size,
-              struct load_funcs *load_funcs)
-{
-    const Elf_Ehdr *ehdr = (const Elf_Ehdr *)image;
-
-    if ( !IS_ELF(*ehdr) )
-        return -EINVAL;
-
-    load_funcs->parseimage = parseelfimage;
-    load_funcs->loadimage = loadelfimage;
-
-    return 0;
-}
-
-static inline int is_loadable_phdr(const Elf_Phdr *phdr)
-{
-    return ((phdr->p_type == PT_LOAD) &&
-            ((phdr->p_flags & (PF_W|PF_X)) != 0));
-}
-
-/*
- * Fallback for kernels containing only the legacy __xen_guest string
- * and no ELF notes.
- */
-static int is_xen_guest_section(const Elf_Shdr *shdr, const char *shstrtab)
-{
-    return strcmp(&shstrtab[shdr->sh_name], "__xen_guest") == 0;
-}
-
-static const char *xen_guest_lookup(
-    const struct domain_setup_info *dsi, int type)
-{
-    const char *xenguest_fallbacks[] = {
-        [XEN_ELFNOTE_ENTRY] = "VIRT_ENTRY=",
-        [XEN_ELFNOTE_HYPERCALL_PAGE] = "HYPERCALL_PAGE=",
-        [XEN_ELFNOTE_VIRT_BASE] = "VIRT_BASE=",
-        [XEN_ELFNOTE_PADDR_OFFSET] = "ELF_PADDR_OFFSET=",
-        [XEN_ELFNOTE_XEN_VERSION] = "XEN_VER=",
-        [XEN_ELFNOTE_GUEST_OS] = "GUEST_OS=",
-        [XEN_ELFNOTE_GUEST_VERSION] = "GUEST_VER=",
-        [XEN_ELFNOTE_LOADER] = "LOADER=",
-        [XEN_ELFNOTE_PAE_MODE] = "PAE=",
-        [XEN_ELFNOTE_FEATURES] = "FEATURES=",
-        [XEN_ELFNOTE_BSD_SYMTAB] = "BSD_SYMTAB=",
-    };
-    const char *fallback;
-    const char *p;
-
-    if ( !dsi->__xen_guest_string )
-        return NULL;
-
-    if ( type > sizeof(xenguest_fallbacks) )
-        return NULL;
-
-    if ( (fallback = xenguest_fallbacks[type]) == NULL )
-        return NULL;
-
-    if ( (p = strstr(dsi->__xen_guest_string,fallback)) == NULL )
-        return NULL;
-
-    return p + strlen(fallback);
-}
-
-static const char *xen_guest_string(
-    const struct domain_setup_info *dsi, int type)
-{
-    const char *p = xen_guest_lookup(dsi, type);
-
-    /*
-     * We special case this since the __xen_guest_section treats the
-     * mere precense of the BSD_SYMTAB string as true or false.
-     */
-    if ( type == XEN_ELFNOTE_BSD_SYMTAB )
-        return p ? "yes" : "no";
-
-    return p;
-}
-
-static unsigned long long xen_guest_numeric(
-    const struct domain_setup_info *dsi, int type, int *defined)
-{
-    const char *p = xen_guest_lookup(dsi, type);
-    unsigned long long value;
-
-    if ( p == NULL )
-        return 0;
-
-    errno = 0;
-    value = strtoull(p, NULL, 0);
-    if ( errno < 0 )
-        return 0;
-
-    /* We special case this since __xen_guest_section contains a PFN
-     * for this field not a virtual address.
-     */
-    if (type == XEN_ELFNOTE_HYPERCALL_PAGE)
-        value = dsi->v_start + (value<<PAGE_SHIFT);
-
-    *defined = 1;
-    return value;
-}
-
-/*
- * Interface to the Xen ELF notes.
- */
-#define ELFNOTE_NAME(_n_)   ((const char*)(_n_) + sizeof(*(_n_)))
-#define ELFNOTE_DESC(_n_)   (ELFNOTE_NAME(_n_) + (((_n_)->namesz+3)&~3))
-#define ELFNOTE_NEXT(_n_)   (ELFNOTE_DESC(_n_) + (((_n_)->descsz+3)&~3))
-
-static int is_xen_elfnote_section(const char *image, const Elf_Shdr *shdr)
-{
-    const Elf_Note *note;
-
-    if ( shdr->sh_type != SHT_NOTE )
-        return 0;
-
-    for ( note = (const Elf_Note *)(image + shdr->sh_offset);
-          note < (const Elf_Note *)(image + shdr->sh_offset + shdr->sh_size);
-          note = (const Elf_Note *)ELFNOTE_NEXT(note) )
-    {
-        if ( !strncmp(ELFNOTE_NAME(note), "Xen", 4) )
-            return 1;
-    }
-
-    return 0;
-}
-
-static const Elf_Note *xen_elfnote_lookup(
-    const struct domain_setup_info *dsi, int type)
-{
-    const Elf_Note *note;
-
-    if ( !dsi->__elfnote_section )
-        return NULL;
-
-    for ( note = (const Elf_Note *)dsi->__elfnote_section;
-          note < (const Elf_Note *)dsi->__elfnote_section_end;
-          note = (const Elf_Note *)ELFNOTE_NEXT(note) )
-    {
-        if ( strncmp(ELFNOTE_NAME(note), "Xen", 4) )
-            continue;
-
-        if ( note->type == type )
-            return note;
-    }
-
-    return NULL;
-}
-
-const char *xen_elfnote_string(const struct domain_setup_info *dsi, int type)
-{
-    const Elf_Note *note;
-
-    if ( !dsi->__elfnote_section )
-        return xen_guest_string(dsi, type);
-
-    note = xen_elfnote_lookup(dsi, type);
-    if ( note == NULL )
-        return NULL;
-
-    return (const char *)ELFNOTE_DESC(note);
-}
-
-unsigned long long xen_elfnote_numeric(const struct domain_setup_info *dsi,
-                                       int type, int *defined)
-{
-    const Elf_Note *note;
-
-    *defined = 0;
-
-    if ( !dsi->__elfnote_section )
-        return xen_guest_numeric(dsi, type, defined);
-
-    note = xen_elfnote_lookup(dsi, type);
-    if ( note == NULL )
-    {
-        return 0;
-    }
-
-    switch ( note->descsz )
-    {
-    case 4:
-        *defined = 1;
-        return *(const uint32_t*)ELFNOTE_DESC(note);
-    case 8:
-        *defined = 1;
-        return *(const uint64_t*)ELFNOTE_DESC(note);
-    default:
-        xc_set_error(XC_INVALID_KERNEL,
-                     "elfnotes: unknown data size %#x for numeric type note 
%#x\n",
-              note->descsz, type);
-        return 0;
-    }
-}
-
-static int parseelfimage(const char *image,
-                         unsigned long image_len,
-                         struct domain_setup_info *dsi)
-{
-    const Elf_Ehdr *ehdr = (const Elf_Ehdr *)image;
-    const Elf_Phdr *phdr;
-    const Elf_Shdr *shdr;
-    Elf_Addr kernstart = ~0, kernend = 0, vaddr, virt_entry;
-    const char *shstrtab, *p;
-    int h, virt_base_defined, elf_pa_off_defined, virt_entry_defined;
-
-    if ( !IS_ELF(*ehdr) )
-    {
-        xc_set_error(XC_INVALID_KERNEL,
-                     "Kernel image does not have an ELF header.");
-        return -EINVAL;
-    }
-
-    if (ehdr->e_machine != ELFMACHINE)
-    {
-        xc_set_error(XC_INVALID_KERNEL,
-                     "Kernel ELF architecture '%d' does not match Xen 
architecture '%d' (%s)",
-                     ehdr->e_machine, ELFMACHINE, ELFMACHINE_DESC);
-        return -EINVAL;
-    }
-    if (ehdr->e_ident[EI_CLASS] != ELFCLASS)
-    {
-        xc_set_error(XC_INVALID_KERNEL,
-                     "Kernel ELF wordsize '%d' does not match Xen wordsize 
'%d' (%s)",
-                     ehdr->e_ident[EI_CLASS], ELFCLASS, ELFCLASS_DESC);
-        return -EINVAL;
-    }
-    if (ehdr->e_ident[EI_DATA] != ELFDATA)
-    {
-        xc_set_error(XC_INVALID_KERNEL,
-                     "Kernel ELF endianness '%d' does not match Xen endianness 
'%d' (%s)",
-                     ehdr->e_ident[EI_DATA], ELFDATA, ELFDATA_DESC);
-        return -EINVAL;
-    }
-    if (ehdr->e_type != ET_EXEC)
-    {
-        xc_set_error(XC_INVALID_KERNEL,
-                     "Kernel ELF type '%d' does not match Xen type '%d'",
-                     ehdr->e_type, ET_EXEC);
-        return -EINVAL;
-    }
-
-    if ( (ehdr->e_phoff + (ehdr->e_phnum*ehdr->e_phentsize)) > image_len )
-    {
-        xc_set_error(XC_INVALID_KERNEL,
-                     "ELF program headers extend beyond end of image.");
-        return -EINVAL;
-    }
-
-    if ( (ehdr->e_shoff + (ehdr->e_shnum*ehdr->e_shentsize)) > image_len )
-    {
-        xc_set_error(XC_INVALID_KERNEL,
-                     "ELF section headers extend beyond end of image.");
-        return -EINVAL;
-    }
-
-    dsi->__elfnote_section = NULL;
-    dsi->__xen_guest_string = NULL;
-
-    /* Look for .notes segment containing at least one Xen note */
-    for ( h = 0; h < ehdr->e_shnum; h++ )
-    {
-        shdr = (const Elf_Shdr *)(
-            image + ehdr->e_shoff + (h*ehdr->e_shentsize));
-        if ( !is_xen_elfnote_section(image, shdr) )
-            continue;
-        dsi->__elfnote_section = (const char *)image + shdr->sh_offset;
-        dsi->__elfnote_section_end =
-            (const char *)image + shdr->sh_offset + shdr->sh_size;
-        break;
-    }
-
-    /* Fall back to looking for the special '__xen_guest' section. */
-    if ( dsi->__elfnote_section == NULL )
-    {
-        /* Find the section-header strings table. */
-        if ( ehdr->e_shstrndx == SHN_UNDEF )
-        {
-            xc_set_error(XC_INVALID_KERNEL,
-                         "ELF image has no section-header strings table.");
-            return -EINVAL;
-        }
-        shdr = (const Elf_Shdr *)(image + ehdr->e_shoff +
-                            (ehdr->e_shstrndx*ehdr->e_shentsize));
-        shstrtab = image + shdr->sh_offset;
-
-        for ( h = 0; h < ehdr->e_shnum; h++ )
-        {
-            shdr = (const Elf_Shdr *)(
-                image + ehdr->e_shoff + (h*ehdr->e_shentsize));
-            if ( is_xen_guest_section(shdr, shstrtab) )
-            {
-                dsi->__xen_guest_string =
-                    (const char *)image + shdr->sh_offset;
-                break;
-            }
-        }
-    }
-
-    /* Check the contents of the Xen notes or guest string. */
-    if ( dsi->__elfnote_section || dsi->__xen_guest_string )
-    {
-        const char *loader = xen_elfnote_string(dsi, XEN_ELFNOTE_LOADER);
-        const char *guest_os = xen_elfnote_string(dsi, XEN_ELFNOTE_GUEST_OS);
-        const char *xen_version =
-            xen_elfnote_string(dsi, XEN_ELFNOTE_XEN_VERSION);
-
-        if ( ( loader == NULL || strncmp(loader, "generic", 7) ) &&
-             ( guest_os == NULL || strncmp(guest_os, "linux", 5) ) )
-        {
-            xc_set_error(XC_INVALID_KERNEL,
-                         "Will only load images built for the generic loader "
-                         "or Linux images");
-            return -EINVAL;
-        }
-
-        if ( xen_version == NULL || strncmp(xen_version, "xen-3.0", 7) )
-        {
-            xc_set_error(XC_INVALID_KERNEL,
-                         "Will only load images built for Xen v3.0");
-            return -EINVAL;
-        }
-    }
-    else
-    {
-#if defined(__x86_64__) || defined(__i386__)
-        xc_set_error(XC_INVALID_KERNEL,
-                     "Not a Xen-ELF image: "
-                     "No ELF notes or '__xen_guest' section found.");
-        return -EINVAL;
-#endif
-    }
-
-    /*
-     * A "bimodal" ELF note indicates the kernel will adjust to the current
-     * paging mode, including handling extended cr3 syntax.  If we have ELF
-     * notes then PAE=yes implies that we must support the extended cr3 syntax.
-     * Otherwise we need to find the [extended-cr3] syntax in the __xen_guest
-     * string. We use strstr() to look for "bimodal" to allow guests to use
-     * "yes,bimodal" or "no,bimodal" for compatibility reasons.
-     */
-
-    dsi->pae_kernel = PAEKERN_no;
-    if ( dsi->__elfnote_section )
-    {

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