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

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



# HG changeset patch
# User awilliam@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


 


Rackspace

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